PostgresPolicyCandidate

On this page

CRD API reference · Served version v1alpha1.

Required fields apply when their containing object is present. Defaults shown are API-server defaults; null requires nullable. Standard metadata follows Kubernetes conventions. Status is controller-owned except documented decisions.

For workflows, see operator guidance, approval, candidates, and ephemeral access.

Spec

PathDefinition
specobject; required. A one-shot, immutable proposal of policy content. The operator plans a candidate in its parent policy's execution context and publishes a `PostgresPolicyPlan` for review; the active policy keeps enforcing throughout. A candidate never executes SQL in any state, and its spec cannot be edited — revising a proposal means creating a successor that names the earlier one in `spec.replaces`. See `docs/src/pages/docs/operator-candidates.md` for the behaviour and `docs/design/adr-001-candidate-api.md` for the API mechanics. Constraints: {"required":["content","policyRef"]}.
specCEL: {"message":"candidate spec is immutable","rule":"self == oldSelf"}. Evaluated with self at this path; oldSelf refers to the previous value on update.
spec.contentobject; required. The proposed policy content.
spec.content.default_ownerstring; optional. Default owner for ALTER DEFAULT PRIVILEGES (e.g. "app_owner"). Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.default_privilegesarray; optional. One-off default privileges. Constraints: {"maxItems":512}.
spec.content.default_privileges[]object; item or branch. Default privilege configuration. The scope rules are also expressed as CEL so the API server rejects a bad entry at apply time. `resolved_scope` enforces the same rules for the CLI, which has no admission step. Constraints: {"required":["grant"]}.
spec.content.default_privileges[]CEL: {"message":"exactly one of `schema` and `scope` must be set","rule":"has(self.schema) != has(self.scope)"}. Evaluated with self at this path; oldSelf refers to the previous value on update.
spec.content.default_privileges[].grantarray; required. Grantee, privileges, and future object kind to reconcile. Constraints: {"maxItems":64}.
spec.content.default_privileges[].grant[]object; item or branch. A single default privilege grant entry. Constraints: {"required":["on_type","privileges"]}.
spec.content.default_privileges[].grant[].ensurestring; optional. Desired privilege state: present grants it; absent explicitly revokes it. Constraints: {"enum":["present","absent"]}.
spec.content.default_privileges[].grant[].on_typestring; required. Kind of future object affected by the default privilege. Constraints: {"enum":["table","view","materialized_view","sequence","function","schema","database","type"]}.
spec.content.default_privileges[].grant[].privilegesarray; required. PostgreSQL privileges to reconcile on the selected objects. Constraints: {"maxItems":16,"minItems":1}.
spec.content.default_privileges[].grant[].privileges[]string; item or branch. PostgreSQL privilege types. Constraints: {"enum":["SELECT","INSERT","UPDATE","DELETE","TRUNCATE","REFERENCES","TRIGGER","EXECUTE","USAGE","CREATE","CONNECT","TEMPORARY"]}.
spec.content.default_privileges[].grant[].rolestring; optional. The role receiving the default privilege. Only used in top-level default_privileges (in profiles, the role is determined by expansion). The exact-uppercase value `PUBLIC` means the PostgreSQL PUBLIC pseudo-role. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.default_privileges[].ownerstring; optional. The role that owns newly created objects. If omitted, uses manifest's default_owner. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.default_privileges[].schemastring; optional. Schema shorthand, equivalent to `scope: {type: schema, schema: ...}`. Exactly one of `schema` and `scope` must be set. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.default_privileges[].scopeobject; optional. Where the defaults apply: one schema, or owner-wide (global). Global scope renders `ALTER DEFAULT PRIVILEGES` without an `IN SCHEMA` clause. Constraints: {"nullable":true,"required":["type"]}.
spec.content.default_privileges[].scopeCEL: {"message":"`schema` is required when type is `schema` and forbidden when type is `global`","rule":"has(self.schema) == (self.type == 'schema')"}. Evaluated with self at this path; oldSelf refers to the previous value on update.
spec.content.default_privileges[].scope.schemastring; optional. Schema name. Required for `type: schema`, forbidden for `type: global`. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.default_privileges[].scope.typestring; required. Global or per-schema scope of the default privilege. Constraints: {"enum":["global","schema"]}.
spec.content.grantsarray; optional. One-off grants. Constraints: {"maxItems":4096}.
spec.content.grants[]object; item or branch. A concrete grant on a specific object or wildcard. Constraints: {"required":["object","privileges","role"]}.
spec.content.grants[].ensurestring; optional. Desired object privilege state: present grants it; absent explicitly revokes it. Constraints: {"enum":["present","absent"]}.
spec.content.grants[].objectobject; required. Object kind and target to which the privileges apply. Constraints: {"required":["type"]}.
spec.content.grants[].objectCEL: {"message":"database grant targets must set `name`","rule":"self.type != 'database' || has(self.name)"}. Evaluated with self at this path; oldSelf refers to the previous value on update.
spec.content.grants[].object.namestring; optional. Object name, or "*" for all objects. Omit for schema-level grants; required for database grants, where it names the connected database. Constraints: {"maxLength":256,"minLength":1,"nullable":true}.
spec.content.grants[].object.schemastring; optional. Schema name. Required for most object types except database. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.grants[].object.typestring; required. PostgreSQL object kind. Constraints: {"enum":["table","view","materialized_view","sequence","function","schema","database","type"]}.
spec.content.grants[].privilegesarray; required. PostgreSQL privileges to reconcile on the selected objects. Constraints: {"maxItems":16,"minItems":1}.
spec.content.grants[].privileges[]string; item or branch. PostgreSQL privilege types. Constraints: {"enum":["SELECT","INSERT","UPDATE","DELETE","TRUNCATE","REFERENCES","TRIGGER","EXECUTE","USAGE","CREATE","CONNECT","TEMPORARY"]}.
spec.content.grants[].rolestring; required. The grantee. The exact-uppercase value `PUBLIC` means the PostgreSQL PUBLIC pseudo-role; any other value is an ordinary role name. Constraints: {"maxLength":63,"minLength":1}.
spec.content.membershipsarray; optional. Membership edges. Constraints: {"maxItems":2048}.
spec.content.memberships[]object; item or branch. A membership declaration — which members belong to a role. Constraints: {"required":["members","role"]}.
spec.content.memberships[].exclusiveboolean; optional. Assert that `members` is the complete membership of `role`: plan a REVOKE for any live member not listed here. Only meaningful for predefined (`pg_*`) and `external: true` roles, whose undeclared members are otherwise left untouched — memberships of ordinary managed roles are already reconciled exhaustively. Defaults to `false` so that adopting pgroles never strips provider-granted memberships (for example `pg_monitor` grants made by a cloud platform) without an explicit assertion.
spec.content.memberships[].membersarray; required. Roles that should receive this membership. Constraints: {"maxItems":512}.
spec.content.memberships[].members[]object; item or branch. A single member of a role. Both `inherit` and `admin` are optional. When omitted, they default to `inherit: true` and `admin: false` at resolution time (in `RoleGraph` construction). Keeping them optional in the CRD avoids Kubernetes injecting default values into the stored resource, which causes perpetual diffs in GitOps tools like ArgoCD. Constraints: {"required":["name"]}.
spec.content.memberships[].members[].adminboolean; optional. Whether the member can administer the role. Defaults to `false`. Constraints: {"nullable":true}.
spec.content.memberships[].members[].inheritboolean; optional. Whether the member inherits the role's privileges. Defaults to `true`. Constraints: {"nullable":true}.
spec.content.memberships[].members[].namestring; required. PostgreSQL role receiving the membership. Constraints: {"maxLength":63,"minLength":1}.
spec.content.memberships[].rolestring; required. PostgreSQL role granted to the listed members. Constraints: {"maxLength":63,"minLength":1}.
spec.content.profilesobject; optional. Reusable privilege profiles. A `BTreeMap` rather than the policy's `HashMap`: the content digest is computed over a canonical serialization, and deterministic iteration order is one less thing that has to be normalised later. Constraints: {"maxProperties":128}.
spec.content.profiles.<name>object; item or branch. A reusable privilege profile.
spec.content.profiles.<name>.configobject; optional. Role-level configuration parameter defaults for generated roles, applied via `ALTER ROLE ... SET parameter = value`. Values support the `{schema}` and `{profile}` placeholders, substituted per `schema x profile` expansion (e.g. `search_path: "{schema}"`). Constraints: {"maxProperties":32}.
spec.content.profiles.<name>.config.<name>string; item or branch. A role configuration parameter value. Values are always strings — quote numbers and booleans (e.g. `statement_timeout: "30000"`, `jit: "off"`). The Kubernetes CRD schema types config values as strings, and the CLI enforces the same rule so a manifest means the same thing whether it is applied with `pgroles` or `kubectl`. PostgreSQL coerces the string to the parameter's type. Constraints: {"maxLength":256}.
spec.content.profiles.<name>.default_privilegesarray; optional. Privileges to grant on future objects created by the configured owner. Constraints: {"maxItems":32}.
spec.content.profiles.<name>.default_privileges[]object; item or branch. Default privilege grant within a profile. Constraints: {"required":["on_type","privileges"]}.
spec.content.profiles.<name>.default_privileges[].ensurestring; optional. Whether the privilege must be present or absent. Matches the top-level `default_privileges` entries, which carry the same field. Constraints: {"enum":["present","absent"]}.
spec.content.profiles.<name>.default_privileges[].on_typestring; required. Kind of future object affected by the default privilege. Constraints: {"enum":["table","view","materialized_view","sequence","function","schema","database","type"]}.
spec.content.profiles.<name>.default_privileges[].privilegesarray; required. PostgreSQL privileges to reconcile on the selected objects. Constraints: {"maxItems":16,"minItems":1}.
spec.content.profiles.<name>.default_privileges[].privileges[]string; item or branch. PostgreSQL privilege types. Constraints: {"enum":["SELECT","INSERT","UPDATE","DELETE","TRUNCATE","REFERENCES","TRIGGER","EXECUTE","USAGE","CREATE","CONNECT","TEMPORARY"]}.
spec.content.profiles.<name>.default_privileges[].rolestring; optional. Grantee role; omitted values use the generated profile role. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.profiles.<name>.grantsarray; optional. Object privilege templates expanded for each bound schema. Constraints: {"maxItems":64}.
spec.content.profiles.<name>.grants[]object; item or branch. Grant template within a profile. Constraints: {"required":["object","privileges"]}.
spec.content.profiles.<name>.grants[].ensurestring; optional. Whether the privilege must be present or absent. Matches the top-level `grants` entries, which carry the same field. Profiles are additive templates, so validation rejects `absent`; the schema accepts it so the API server does not prune the value before that check can name it. Constraints: {"enum":["present","absent"]}.
spec.content.profiles.<name>.grants[].objectobject; required. Object kind and target to which the privileges apply. Constraints: {"required":["type"]}.
spec.content.profiles.<name>.grants[].object.namestring; optional. Object name; omission selects the object-kind scope supported by the profile. Constraints: {"maxLength":256,"minLength":1,"nullable":true}.
spec.content.profiles.<name>.grants[].object.typestring; required. PostgreSQL object kind. Constraints: {"enum":["table","view","materialized_view","sequence","function","schema","database","type"]}.
spec.content.profiles.<name>.grants[].privilegesarray; required. PostgreSQL privileges to reconcile on the selected objects. Constraints: {"maxItems":16,"minItems":1}.
spec.content.profiles.<name>.grants[].privileges[]string; item or branch. PostgreSQL privilege types. Constraints: {"enum":["SELECT","INSERT","UPDATE","DELETE","TRUNCATE","REFERENCES","TRIGGER","EXECUTE","USAGE","CREATE","CONNECT","TEMPORARY"]}.
spec.content.profiles.<name>.inheritboolean; optional. Whether privileges from role memberships are inherited automatically. Constraints: {"nullable":true}.
spec.content.profiles.<name>.loginboolean; optional. Whether the role may initiate database sessions. Constraints: {"nullable":true}.
spec.content.reconciliation_modestring; optional. Convergence strategy: how aggressively to converge the database. Constraints: {"enum":["authoritative","additive","adopt"]}.
spec.content.retirementsarray; optional. Explicit role-retirement workflows for roles that should be removed. Constraints: {"maxItems":512}.
spec.content.retirements[]object; item or branch. Declarative workflow for retiring an existing role. Constraints: {"required":["role"]}.
spec.content.retirements[].drop_ownedboolean; optional. Whether to run `DROP OWNED BY` before dropping the role.
spec.content.retirements[].reassign_owned_tostring; optional. Optional successor role for `REASSIGN OWNED BY ... TO ...`. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.retirements[].rolestring; required. The role to retire and ultimately drop. Constraints: {"maxLength":63,"minLength":1}.
spec.content.retirements[].terminate_sessionsboolean; optional. Whether to terminate other active sessions for the role before drop.
spec.content.role_patternstring; optional. Default role naming pattern. Schema bindings can override it. Supports `{schema}` and requires `{profile}`; falls back to `{schema}-{profile}`. Constraints: {"maxLength":128,"minLength":1,"nullable":true}.
spec.content.rolesarray; optional. One-off role definitions. Constraints: {"maxItems":1024}.
spec.content.roles[]object; item or branch. A concrete PostgreSQL role definition. Constraints: {"required":["name"]}.
spec.content.roles[].bypassrlsboolean; optional. Whether the role bypasses row-level security. Constraints: {"nullable":true}.
spec.content.roles[].commentstring; optional. Descriptive PostgreSQL role comment. Constraints: {"maxLength":256,"nullable":true}.
spec.content.roles[].configobject; optional. Role-level configuration parameter defaults, applied via `ALTER ROLE ... SET parameter = value` (e.g. `role: combined`, `search_path: app`). Settings present on the role in the database but absent here are RESET in authoritative mode. Constraints: {"maxProperties":32}.
spec.content.roles[].config.<name>string; item or branch. A role configuration parameter value. Values are always strings — quote numbers and booleans (e.g. `statement_timeout: "30000"`, `jit: "off"`). The Kubernetes CRD schema types config values as strings, and the CLI enforces the same rule so a manifest means the same thing whether it is applied with `pgroles` or `kubectl`. PostgreSQL coerces the string to the parameter's type. Constraints: {"maxLength":256}.
spec.content.roles[].connection_limitinteger; optional. Maximum concurrent connections for the role; -1 means unlimited. Constraints: {"format":"int32","nullable":true}.
spec.content.roles[].createdbboolean; optional. Whether the role may create databases. Constraints: {"nullable":true}.
spec.content.roles[].createroleboolean; optional. Whether the role may create and administer roles, subject to server-version rules. Constraints: {"nullable":true}.
spec.content.roles[].externalboolean; optional. Treat this role as externally managed. The operator may reference it in grants, ownership, and memberships, but will not create, alter, drop, or password-manage it. Declared membership edges remain managed.
spec.content.roles[].inheritboolean; optional. Whether privileges from role memberships are inherited automatically. Constraints: {"nullable":true}.
spec.content.roles[].loginboolean; optional. Whether the role may initiate database sessions. Constraints: {"nullable":true}.
spec.content.roles[].namestring; required. PostgreSQL role name. Constraints: {"maxLength":63,"minLength":1}.
spec.content.roles[].passwordobject; optional. Password source for this role. Either a reference to an existing Secret or a request for the operator to generate one. Constraints: {"nullable":true}.
spec.content.roles[].password.generateobject; optional. Generate a random password and store it in a new Kubernetes Secret. Mutually exclusive with `secretRef`. Constraints: {"nullable":true}.
spec.content.roles[].password.generate.lengthinteger; optional. Password length. Defaults to 32. Minimum 16, maximum 128. Constraints: {"format":"uint32","minimum":0.0,"nullable":true}.
spec.content.roles[].password.generate.secretKeystring; optional. Key within the generated Secret. Defaults to `password`. Constraints: {"maxLength":253,"minLength":1,"nullable":true}.
spec.content.roles[].password.generate.secretNamestring; optional. Override the generated Secret name. Defaults to `{policy}-pgr-{role}`. Constraints: {"maxLength":253,"minLength":1,"nullable":true}.
spec.content.roles[].password.secretKeystring; optional. Key within the referenced Secret. Defaults to the role name. Only used with `secretRef`. Constraints: {"maxLength":253,"minLength":1,"nullable":true}.
spec.content.roles[].password.secretRefobject; optional. Reference to an existing Kubernetes Secret containing the password. Mutually exclusive with `generate`. Constraints: {"nullable":true,"required":["name"]}.
spec.content.roles[].password.secretRef.namestring; required. Name of the Secret. Constraints: {"maxLength":253,"minLength":1}.
spec.content.roles[].password_valid_untilstring; optional. Password expiration timestamp (ISO 8601, e.g. "2025-12-31T00:00:00Z"). Constraints: {"maxLength":64,"nullable":true}.
spec.content.roles[].preserve_undeclared_grantsboolean; optional. Preserve this role's undeclared in-scope object grants during convergence. Revokes against the role are skipped unless the revoked privileges are explicitly asserted absent (`ensure: absent`).
spec.content.roles[].replicationboolean; optional. Whether the role may initiate replication connections. Constraints: {"nullable":true}.
spec.content.roles[].superuserboolean; optional. Whether the role bypasses PostgreSQL permission checks as a superuser. Constraints: {"nullable":true}.
spec.content.schemasarray; optional. Schema bindings that expand profiles into concrete roles/grants. Constraints: {"maxItems":1024}.
spec.content.schemas[]object; item or branch. Associates a PostgreSQL schema with one or more reusable privilege profiles. Constraints: {"required":["name"]}.
spec.content.schemas[].namestring; required. PostgreSQL schema name. Constraints: {"maxLength":63,"minLength":1}.
spec.content.schemas[].ownerstring; optional. Override default_owner for this schema's default privileges. Constraints: {"maxLength":63,"minLength":1,"nullable":true}.
spec.content.schemas[].profilesarray; optional. Profile names to expand for this schema. Constraints: {"maxItems":64}.
spec.content.schemas[].profiles[]string; item or branch. Constraints on this array item, map value, or conditional schema. Constraints: {"maxLength":63,"minLength":1}.
spec.content.schemas[].role_patternstring; optional. Role naming pattern. Supports `{schema}` and `{profile}` placeholders. Overrides the policy pattern; otherwise inherits it, falling back to `"{schema}-{profile}"`. Constraints: {"maxLength":128,"minLength":1,"nullable":true}.
spec.policyRefobject; required. The `PostgresPolicy` this candidate proposes content for. Resolved in the candidate's own namespace: an owner reference cannot cross namespaces, so neither can this. Constraints: {"required":["name"]}.
spec.policyRef.namestring; required. Name of the referenced resource in the same namespace. Constraints: {"maxLength":253,"minLength":1}.
spec.replacesstring; optional. Name of an earlier candidate this one supersedes. Supersession is always explicit. The operator never infers it from creator identity, because CI typically files every team's candidates under one service account. Constraints: {"maxLength":253,"minLength":1,"nullable":true}.
spec.targetobject; optional. Preview the content against a different connection than the parent policy's. Credentials, locking and the plan's bound target identity all follow the override, which is why such a plan is a preview and never a migration step. Constraints: {"nullable":true,"required":["connectionRef"]}.
spec.target.connectionRefobject; required. Connection information for the candidate evaluation target. Constraints: {"required":["key","secretName"]}.
spec.target.connectionRef.keystring; required. Key within the Secret holding the connection URL. Constraints: {"maxLength":253,"minLength":1}.
spec.target.connectionRef.secretNamestring; required. Name of the Secret in the candidate's namespace. Constraints: {"maxLength":253,"minLength":1}.

Status (read-only except decisions)

PathDefinition
statusobject; optional. Status of a `PostgresPolicyCandidate`. `phase` is a printable summary; conditions are the source of truth. Constraints: {"nullable":true}.
status.conditionsarray; optional. Controller observations about candidate validity, planning, approval, and promotion. Default: []. Constraints: {"maxItems":16}.
status.conditions[]object; item or branch. A condition on the `PostgresPolicy` resource. Constraints: {"required":["status","type"]}.
status.conditions[].last_transition_timestring; optional. Last time the condition transitioned. Constraints: {"nullable":true}.
status.conditions[].messagestring; optional. Human-readable message. Constraints: {"nullable":true}.
status.conditions[].reasonstring; optional. Human-readable reason for the condition. Constraints: {"nullable":true}.
status.conditions[].statusstring; required. Status: "True", "False", or "Unknown".
status.conditions[].typestring; required. Controller-defined condition type, such as Ready, Reconciling, or Degraded. This is an open vocabulary; consult status guidance for operational meanings.
status.contentDigeststring; optional. Canonical digest of `spec.content`, computed by `pgroles_core::candidate::compute_content_digest`. This is what promotion is verified against. Constraints: {"maxLength":128,"nullable":true}.
status.observedGenerationinteger; optional. The `.metadata.generation` that was last observed. A candidate spec is immutable, so this advances at most once. Constraints: {"format":"int64","nullable":true}.
status.phasestring; optional. Current candidate evaluation and promotion phase. Default: "Pending". Constraints: {"enum":["Pending","Planned","Promoted","Superseded","Stale"]}.
status.planRefobject; optional. The `PostgresPolicyPlan` produced for this candidate. Constraints: {"nullable":true,"required":["name"]}.
status.planRef.namestring; required. Name of the PostgresPolicyPlan in the same namespace.

Download the complete served OpenAPI schema for structural composition and all Kubernetes extensions.

Generated with crdgen --docs-dir; edit the Rust schema descriptions to change this reference.