{
  "description": "Auto-generated derived type for PostgresPolicySpec via `CustomResource`",
  "properties": {
    "spec": {
      "description": "Spec for a `PostgresPolicy` custom resource.\n\nDefines the desired state of PostgreSQL roles, grants, default privileges,\nand memberships for a single database connection.",
      "properties": {
        "allow_schema_owner_transfers": {
          "default": false,
          "description": "Permit adopt mode to transfer schema ownership (`ALTER SCHEMA ...\nOWNER TO ...`) on schemas whose live owner differs. Without this,\napply-mode adopt policies fail such plans with an\n`OwnerTransferBlocked` condition — the operator equivalent of the\nCLI's `--allow-schema-owner-transfers`.",
          "type": "boolean"
        },
        "approval": {
          "description": "Approval mode for plans generated by this policy.\n\nSet this explicitly. When omitted it is currently inferred from `spec.mode`\n(`apply` implies `auto`, `observe` implies `manual`), which leaves a policy's\nexecution gate invisible on the object. That inference is deprecated: a\npolicy relying on it reports an `ApprovalUnset` status condition, and a\nfuture release will reject a policy that omits this field.",
          "enum": [
            "manual",
            "auto"
          ],
          "nullable": true,
          "type": "string"
        },
        "connection": {
          "description": "Database connection configuration.",
          "properties": {
            "params": {
              "description": "Structured connection parameters. Each field is either a plain string\nor a reference to a Secret key. Mutually exclusive with `secretRef`.",
              "nullable": true,
              "properties": {
                "auth": {
                  "description": "Provider-backed authentication for connections that use short-lived\ncredentials instead of a static PostgreSQL password.",
                  "nullable": true,
                  "oneOf": [
                    {
                      "required": [
                        "type"
                      ]
                    }
                  ],
                  "properties": {
                    "impersonateServiceAccount": {
                      "description": "Target Google service account to impersonate before requesting the\nCloud SQL login token. Omit to use the pod's bound identity.",
                      "nullable": true,
                      "type": "string"
                    },
                    "scope": {
                      "description": "OAuth scope requested for the access token.",
                      "nullable": true,
                      "type": "string"
                    },
                    "type": {
                      "description": "Provider authentication mechanism.",
                      "enum": [
                        "gcp_workload_identity"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "dbname": {
                  "description": "Database name as a literal value.",
                  "nullable": true,
                  "type": "string"
                },
                "dbnameSecret": {
                  "description": "Database name from a Secret key.",
                  "nullable": true,
                  "properties": {
                    "key": {
                      "description": "Key within the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "name": {
                      "description": "Name of the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "key",
                    "name"
                  ],
                  "type": "object"
                },
                "host": {
                  "description": "PostgreSQL host as a literal value.",
                  "nullable": true,
                  "type": "string"
                },
                "hostSecret": {
                  "description": "PostgreSQL host from a Secret key.",
                  "nullable": true,
                  "properties": {
                    "key": {
                      "description": "Key within the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "name": {
                      "description": "Name of the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "key",
                    "name"
                  ],
                  "type": "object"
                },
                "password": {
                  "description": "Password as a literal value (not recommended for production).",
                  "nullable": true,
                  "type": "string"
                },
                "passwordSecret": {
                  "description": "Password from a Secret key (recommended).",
                  "nullable": true,
                  "properties": {
                    "key": {
                      "description": "Key within the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "name": {
                      "description": "Name of the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "key",
                    "name"
                  ],
                  "type": "object"
                },
                "port": {
                  "description": "Port as a literal value. Defaults to 5432 if neither port nor portSecret is set.",
                  "format": "uint16",
                  "maximum": 65535.0,
                  "minimum": 0.0,
                  "nullable": true,
                  "type": "integer"
                },
                "portSecret": {
                  "description": "Port from a Secret key.",
                  "nullable": true,
                  "properties": {
                    "key": {
                      "description": "Key within the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "name": {
                      "description": "Name of the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "key",
                    "name"
                  ],
                  "type": "object"
                },
                "setRole": {
                  "description": "Run `SET ROLE \"<value>\"` once on every pooled connection. Useful when\nthe operator authenticates as a low-privilege identity (e.g. a Cloud\nSQL IAM user) that has been granted membership in a privileged role\nlike `cloudsqlsuperuser` — PostgreSQL does not inherit role\n*attributes* (`CREATEROLE`, `CREATEDB`, …) through `GRANT … TO …`, so\n`SET ROLE` is required for the connection to act with the parent\nrole's attributes.\n\nMust be a simple PostgreSQL identifier matching\n`^[A-Za-z_][A-Za-z0-9_$-]*$`. The pattern intentionally excludes `@`\nand `.` — `setRole` is for switching to a privileged *group* role\n(e.g. `cloudsqlsuperuser`), not an IAM-style principal like\n`pgroles-operator@project.iam`, which has no extra attributes to\ninherit via `SET ROLE`.",
                  "nullable": true,
                  "pattern": "^[A-Za-z_][A-Za-z0-9_$-]*$",
                  "type": "string"
                },
                "sslMode": {
                  "description": "SSL mode as a literal value.",
                  "nullable": true,
                  "type": "string"
                },
                "sslModeSecret": {
                  "description": "SSL mode from a Secret key.",
                  "nullable": true,
                  "properties": {
                    "key": {
                      "description": "Key within the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "name": {
                      "description": "Name of the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "key",
                    "name"
                  ],
                  "type": "object"
                },
                "username": {
                  "description": "Username as a literal value.",
                  "nullable": true,
                  "type": "string"
                },
                "usernameSecret": {
                  "description": "Username from a Secret key.",
                  "nullable": true,
                  "properties": {
                    "key": {
                      "description": "Key within the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "name": {
                      "description": "Name of the Secret.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "key",
                    "name"
                  ],
                  "type": "object"
                }
              },
              "type": "object"
            },
            "requirePhysicalIdentity": {
              "description": "Refuse to plan or execute unless the target's *physical* identity —\n`pg_control_system().system_identifier` — can be read.\n\nOff by default: every mainstream managed PostgreSQL exposes the\nidentifier, but PostgreSQL-protocol engines that are not PostgreSQL\n(CockroachDB, Spanner's PostgreSQL interface, Redshift, Aurora DSQL) do\nnot implement it, and those targets run on the logical identity alone.\nSet it where a real PostgreSQL is expected and losing the strongest\nhalf of the target binding should stop reconciliation rather than\nsilently weaken it.",
              "nullable": true,
              "type": "boolean"
            },
            "secretKey": {
              "description": "Key within the Secret to read. Defaults to `DATABASE_URL`.\nOnly used with `secretRef`.",
              "nullable": true,
              "type": "string"
            },
            "secretRef": {
              "description": "Reference to a Kubernetes Secret containing a connection URL.\nMutually exclusive with `params`.",
              "nullable": true,
              "properties": {
                "name": {
                  "description": "Name of the Secret.",
                  "maxLength": 253,
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "name"
              ],
              "type": "object"
            }
          },
          "type": "object"
        },
        "default_owner": {
          "description": "Default owner for ALTER DEFAULT PRIVILEGES (e.g. \"app_owner\").",
          "maxLength": 63,
          "minLength": 1,
          "nullable": true,
          "type": "string"
        },
        "default_privileges": {
          "default": [],
          "description": "One-off default privileges.",
          "items": {
            "description": "Default privilege configuration.\n\nThe scope rules are also expressed as CEL so the API server rejects a bad\nentry at apply time. `resolved_scope` enforces the same rules for the CLI,\nwhich has no admission step.",
            "properties": {
              "grant": {
                "description": "Grantee, privileges, and future object kind to reconcile.",
                "items": {
                  "description": "A single default privilege grant entry.",
                  "properties": {
                    "ensure": {
                      "description": "Desired privilege state: present grants it; absent explicitly revokes it.",
                      "enum": [
                        "present",
                        "absent"
                      ],
                      "type": "string"
                    },
                    "on_type": {
                      "description": "Kind of future object affected by the default privilege.",
                      "enum": [
                        "table",
                        "view",
                        "materialized_view",
                        "sequence",
                        "function",
                        "schema",
                        "database",
                        "type"
                      ],
                      "type": "string"
                    },
                    "privileges": {
                      "description": "PostgreSQL privileges to reconcile on the selected objects.",
                      "items": {
                        "description": "PostgreSQL privilege types.",
                        "enum": [
                          "SELECT",
                          "INSERT",
                          "UPDATE",
                          "DELETE",
                          "TRUNCATE",
                          "REFERENCES",
                          "TRIGGER",
                          "EXECUTE",
                          "USAGE",
                          "CREATE",
                          "CONNECT",
                          "TEMPORARY"
                        ],
                        "type": "string"
                      },
                      "maxItems": 16,
                      "minItems": 1,
                      "type": "array"
                    },
                    "role": {
                      "description": "The role receiving the default privilege. Only used in top-level default_privileges\n(in profiles, the role is determined by expansion). The exact-uppercase\nvalue `PUBLIC` means the PostgreSQL PUBLIC pseudo-role.",
                      "maxLength": 63,
                      "minLength": 1,
                      "nullable": true,
                      "type": "string"
                    }
                  },
                  "required": [
                    "on_type",
                    "privileges"
                  ],
                  "type": "object"
                },
                "maxItems": 64,
                "type": "array"
              },
              "owner": {
                "description": "The role that owns newly created objects. If omitted, uses manifest's default_owner.",
                "maxLength": 63,
                "minLength": 1,
                "nullable": true,
                "type": "string"
              },
              "schema": {
                "description": "Schema shorthand, equivalent to `scope: {type: schema, schema: ...}`.\nExactly one of `schema` and `scope` must be set.",
                "maxLength": 63,
                "minLength": 1,
                "nullable": true,
                "type": "string"
              },
              "scope": {
                "description": "Where the defaults apply: one schema, or owner-wide (global). Global\nscope renders `ALTER DEFAULT PRIVILEGES` without an `IN SCHEMA` clause.",
                "nullable": true,
                "properties": {
                  "schema": {
                    "description": "Schema name. Required for `type: schema`, forbidden for `type: global`.",
                    "maxLength": 63,
                    "minLength": 1,
                    "nullable": true,
                    "type": "string"
                  },
                  "type": {
                    "description": "Global or per-schema scope of the default privilege.",
                    "enum": [
                      "global",
                      "schema"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object",
                "x-kubernetes-validations": [
                  {
                    "message": "`schema` is required when type is `schema` and forbidden when type is `global`",
                    "rule": "has(self.schema) == (self.type == 'schema')"
                  }
                ]
              }
            },
            "required": [
              "grant"
            ],
            "type": "object",
            "x-kubernetes-validations": [
              {
                "message": "exactly one of `schema` and `scope` must be set",
                "rule": "has(self.schema) != has(self.scope)"
              }
            ]
          },
          "maxItems": 512,
          "type": "array"
        },
        "grants": {
          "default": [],
          "description": "One-off grants.",
          "items": {
            "description": "A concrete grant on a specific object or wildcard.",
            "properties": {
              "ensure": {
                "description": "Desired object privilege state: present grants it; absent explicitly revokes it.",
                "enum": [
                  "present",
                  "absent"
                ],
                "type": "string"
              },
              "object": {
                "description": "Object kind and target to which the privileges apply.",
                "properties": {
                  "name": {
                    "description": "Object name, or \"*\" for all objects. Omit for schema-level grants;\nrequired for database grants, where it names the connected database.",
                    "maxLength": 256,
                    "minLength": 1,
                    "nullable": true,
                    "type": "string"
                  },
                  "schema": {
                    "description": "Schema name. Required for most object types except database.",
                    "maxLength": 63,
                    "minLength": 1,
                    "nullable": true,
                    "type": "string"
                  },
                  "type": {
                    "description": "PostgreSQL object kind.",
                    "enum": [
                      "table",
                      "view",
                      "materialized_view",
                      "sequence",
                      "function",
                      "schema",
                      "database",
                      "type"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object",
                "x-kubernetes-validations": [
                  {
                    "message": "database grant targets must set `name`",
                    "rule": "self.type != 'database' || has(self.name)"
                  }
                ]
              },
              "privileges": {
                "description": "PostgreSQL privileges to reconcile on the selected objects.",
                "items": {
                  "description": "PostgreSQL privilege types.",
                  "enum": [
                    "SELECT",
                    "INSERT",
                    "UPDATE",
                    "DELETE",
                    "TRUNCATE",
                    "REFERENCES",
                    "TRIGGER",
                    "EXECUTE",
                    "USAGE",
                    "CREATE",
                    "CONNECT",
                    "TEMPORARY"
                  ],
                  "type": "string"
                },
                "maxItems": 16,
                "minItems": 1,
                "type": "array"
              },
              "role": {
                "description": "The grantee. The exact-uppercase value `PUBLIC` means the PostgreSQL\nPUBLIC pseudo-role; any other value is an ordinary role name.",
                "maxLength": 63,
                "minLength": 1,
                "type": "string"
              }
            },
            "required": [
              "object",
              "privileges",
              "role"
            ],
            "type": "object"
          },
          "maxItems": 4096,
          "type": "array"
        },
        "interval": {
          "default": "5m",
          "description": "Reconciliation interval (e.g. \"5m\", \"1h\"). Defaults to \"5m\".",
          "type": "string"
        },
        "memberships": {
          "default": [],
          "description": "Membership edges.",
          "items": {
            "description": "A membership declaration — which members belong to a role.",
            "properties": {
              "exclusive": {
                "description": "Assert that `members` is the complete membership of `role`: plan a\nREVOKE for any live member not listed here. Only meaningful for\npredefined (`pg_*`) and `external: true` roles, whose undeclared\nmembers are otherwise left untouched — memberships of ordinary managed\nroles are already reconciled exhaustively. Defaults to `false` so that\nadopting pgroles never strips provider-granted memberships (for\nexample `pg_monitor` grants made by a cloud platform) without an\nexplicit assertion.",
                "type": "boolean"
              },
              "members": {
                "description": "Roles that should receive this membership.",
                "items": {
                  "description": "A single member of a role.\n\nBoth `inherit` and `admin` are optional. When omitted, they default to\n`inherit: true` and `admin: false` at resolution time (in `RoleGraph`\nconstruction). Keeping them optional in the CRD avoids Kubernetes\ninjecting default values into the stored resource, which causes\nperpetual diffs in GitOps tools like ArgoCD.",
                  "properties": {
                    "admin": {
                      "description": "Whether the member can administer the role. Defaults to `false`.",
                      "nullable": true,
                      "type": "boolean"
                    },
                    "inherit": {
                      "description": "Whether the member inherits the role's privileges. Defaults to `true`.",
                      "nullable": true,
                      "type": "boolean"
                    },
                    "name": {
                      "description": "PostgreSQL role receiving the membership.",
                      "maxLength": 63,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                },
                "maxItems": 512,
                "type": "array"
              },
              "role": {
                "description": "PostgreSQL role granted to the listed members.",
                "maxLength": 63,
                "minLength": 1,
                "type": "string"
              }
            },
            "required": [
              "members",
              "role"
            ],
            "type": "object"
          },
          "maxItems": 2048,
          "type": "array"
        },
        "mode": {
          "default": "apply",
          "description": "Reconciliation mode: `apply` executes SQL, `observe` computes drift only.",
          "enum": [
            "apply",
            "observe",
            "plan"
          ],
          "type": "string"
        },
        "profiles": {
          "additionalProperties": {
            "description": "A reusable privilege profile.",
            "properties": {
              "config": {
                "additionalProperties": {
                  "description": "A role configuration parameter value.\n\nValues are always strings — quote numbers and booleans (e.g.\n`statement_timeout: \"30000\"`, `jit: \"off\"`). The Kubernetes CRD schema\ntypes config values as strings, and the CLI enforces the same rule so a\nmanifest means the same thing whether it is applied with `pgroles` or\n`kubectl`. PostgreSQL coerces the string to the parameter's type.",
                  "maxLength": 256,
                  "type": "string"
                },
                "description": "Role-level configuration parameter defaults for generated roles,\napplied via `ALTER ROLE ... SET parameter = value`. Values support the\n`{schema}` and `{profile}` placeholders, substituted per `schema x\nprofile` expansion (e.g. `search_path: \"{schema}\"`).",
                "maxProperties": 32,
                "type": "object"
              },
              "default_privileges": {
                "default": [],
                "description": "Privileges to grant on future objects created by the configured owner.",
                "items": {
                  "description": "Default privilege grant within a profile.",
                  "properties": {
                    "ensure": {
                      "description": "Whether the privilege must be present or absent. Matches the\ntop-level `default_privileges` entries, which carry the same field.",
                      "enum": [
                        "present",
                        "absent"
                      ],
                      "type": "string"
                    },
                    "on_type": {
                      "description": "Kind of future object affected by the default privilege.",
                      "enum": [
                        "table",
                        "view",
                        "materialized_view",
                        "sequence",
                        "function",
                        "schema",
                        "database",
                        "type"
                      ],
                      "type": "string"
                    },
                    "privileges": {
                      "description": "PostgreSQL privileges to reconcile on the selected objects.",
                      "items": {
                        "description": "PostgreSQL privilege types.",
                        "enum": [
                          "SELECT",
                          "INSERT",
                          "UPDATE",
                          "DELETE",
                          "TRUNCATE",
                          "REFERENCES",
                          "TRIGGER",
                          "EXECUTE",
                          "USAGE",
                          "CREATE",
                          "CONNECT",
                          "TEMPORARY"
                        ],
                        "type": "string"
                      },
                      "maxItems": 16,
                      "minItems": 1,
                      "type": "array"
                    },
                    "role": {
                      "description": "Grantee role; omitted values use the generated profile role.",
                      "maxLength": 63,
                      "minLength": 1,
                      "nullable": true,
                      "type": "string"
                    }
                  },
                  "required": [
                    "on_type",
                    "privileges"
                  ],
                  "type": "object"
                },
                "maxItems": 32,
                "type": "array"
              },
              "grants": {
                "default": [],
                "description": "Object privilege templates expanded for each bound schema.",
                "items": {
                  "description": "Grant template within a profile.",
                  "properties": {
                    "ensure": {
                      "description": "Whether the privilege must be present or absent. Matches the top-level\n`grants` entries, which carry the same field. Profiles are additive\ntemplates, so validation rejects `absent`; the schema accepts it so the\nAPI server does not prune the value before that check can name it.",
                      "enum": [
                        "present",
                        "absent"
                      ],
                      "type": "string"
                    },
                    "object": {
                      "description": "Object kind and target to which the privileges apply.",
                      "properties": {
                        "name": {
                          "description": "Object name; omission selects the object-kind scope supported by the profile.",
                          "maxLength": 256,
                          "minLength": 1,
                          "nullable": true,
                          "type": "string"
                        },
                        "type": {
                          "description": "PostgreSQL object kind.",
                          "enum": [
                            "table",
                            "view",
                            "materialized_view",
                            "sequence",
                            "function",
                            "schema",
                            "database",
                            "type"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object"
                    },
                    "privileges": {
                      "description": "PostgreSQL privileges to reconcile on the selected objects.",
                      "items": {
                        "description": "PostgreSQL privilege types.",
                        "enum": [
                          "SELECT",
                          "INSERT",
                          "UPDATE",
                          "DELETE",
                          "TRUNCATE",
                          "REFERENCES",
                          "TRIGGER",
                          "EXECUTE",
                          "USAGE",
                          "CREATE",
                          "CONNECT",
                          "TEMPORARY"
                        ],
                        "type": "string"
                      },
                      "maxItems": 16,
                      "minItems": 1,
                      "type": "array"
                    }
                  },
                  "required": [
                    "object",
                    "privileges"
                  ],
                  "type": "object"
                },
                "maxItems": 64,
                "type": "array"
              },
              "inherit": {
                "description": "Whether privileges from role memberships are inherited automatically.",
                "nullable": true,
                "type": "boolean"
              },
              "login": {
                "description": "Whether the role may initiate database sessions.",
                "nullable": true,
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "default": {},
          "description": "Reusable privilege profiles.",
          "maxProperties": 128,
          "type": "object"
        },
        "reconciliation_mode": {
          "default": "authoritative",
          "description": "Convergence strategy: how aggressively to converge the database.\n\n- `authoritative` (default): revoke undeclared managed privileges and\n  drop undeclared roles within the configured inspection scope. External\n  roles are not altered or dropped; PUBLIC targets require explicit rules.\n- `additive`: only grant, never revoke — safe for incremental adoption;\n  `ensure: absent` assertions are ignored with a warning condition.\n- `adopt`: manage declared roles fully, but never drop undeclared roles.",
          "enum": [
            "authoritative",
            "additive",
            "adopt"
          ],
          "type": "string"
        },
        "retirements": {
          "default": [],
          "description": "Explicit role-retirement workflows for roles that should be removed.\n\nKeyed by `role`, which is this list's unique identifier rather than\n`name`. Retiring one role twice was never meaningful, so the key is\nunambiguous.",
          "items": {
            "description": "Declarative workflow for retiring an existing role.",
            "properties": {
              "drop_owned": {
                "default": false,
                "description": "Whether to run `DROP OWNED BY` before dropping the role.",
                "type": "boolean"
              },
              "reassign_owned_to": {
                "description": "Optional successor role for `REASSIGN OWNED BY ... TO ...`.",
                "maxLength": 63,
                "minLength": 1,
                "nullable": true,
                "type": "string"
              },
              "role": {
                "description": "The role to retire and ultimately drop.",
                "maxLength": 63,
                "minLength": 1,
                "type": "string"
              },
              "terminate_sessions": {
                "default": false,
                "description": "Whether to terminate other active sessions for the role before drop.",
                "type": "boolean"
              }
            },
            "required": [
              "role"
            ],
            "type": "object"
          },
          "maxItems": 512,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "role"
          ],
          "x-kubernetes-list-type": "map"
        },
        "role_pattern": {
          "description": "Default role naming pattern. Schema bindings can override it. Supports `{schema}` and requires `{profile}`; falls back to `{schema}-{profile}`.",
          "maxLength": 128,
          "minLength": 1,
          "nullable": true,
          "type": "string"
        },
        "roles": {
          "default": [],
          "description": "One-off role definitions.\n\nKeyed by `name`; see `schemas`.",
          "items": {
            "description": "A concrete PostgreSQL role definition.",
            "properties": {
              "bypassrls": {
                "description": "Whether the role bypasses row-level security.",
                "nullable": true,
                "type": "boolean"
              },
              "comment": {
                "description": "Descriptive PostgreSQL role comment.",
                "maxLength": 256,
                "nullable": true,
                "type": "string"
              },
              "config": {
                "additionalProperties": {
                  "description": "A role configuration parameter value.\n\nValues are always strings — quote numbers and booleans (e.g.\n`statement_timeout: \"30000\"`, `jit: \"off\"`). The Kubernetes CRD schema\ntypes config values as strings, and the CLI enforces the same rule so a\nmanifest means the same thing whether it is applied with `pgroles` or\n`kubectl`. PostgreSQL coerces the string to the parameter's type.",
                  "maxLength": 256,
                  "type": "string"
                },
                "description": "Role-level configuration parameter defaults, applied via\n`ALTER ROLE ... SET parameter = value` (e.g. `role: combined`,\n`search_path: app`). Settings present on the role in the database but\nabsent here are RESET in authoritative mode.",
                "maxProperties": 32,
                "type": "object"
              },
              "connection_limit": {
                "description": "Maximum concurrent connections for the role; -1 means unlimited.",
                "format": "int32",
                "nullable": true,
                "type": "integer"
              },
              "createdb": {
                "description": "Whether the role may create databases.",
                "nullable": true,
                "type": "boolean"
              },
              "createrole": {
                "description": "Whether the role may create and administer roles, subject to server-version rules.",
                "nullable": true,
                "type": "boolean"
              },
              "external": {
                "default": false,
                "description": "Treat this role as externally managed. The operator may reference it in\ngrants, ownership, and memberships, but will not create, alter, drop,\nor password-manage it. Declared membership edges remain managed.",
                "type": "boolean"
              },
              "inherit": {
                "description": "Whether privileges from role memberships are inherited automatically.",
                "nullable": true,
                "type": "boolean"
              },
              "login": {
                "description": "Whether the role may initiate database sessions.",
                "nullable": true,
                "type": "boolean"
              },
              "name": {
                "description": "PostgreSQL role name.",
                "maxLength": 63,
                "minLength": 1,
                "type": "string"
              },
              "password": {
                "description": "Password source for this role. Either a reference to an existing Secret\nor a request for the operator to generate one.",
                "nullable": true,
                "properties": {
                  "generate": {
                    "description": "Generate a random password and store it in a new Kubernetes Secret.\nMutually exclusive with `secretRef`.",
                    "nullable": true,
                    "properties": {
                      "length": {
                        "description": "Password length. Defaults to 32. Minimum 16, maximum 128.",
                        "format": "uint32",
                        "minimum": 0.0,
                        "nullable": true,
                        "type": "integer"
                      },
                      "secretKey": {
                        "description": "Key within the generated Secret. Defaults to `password`.",
                        "maxLength": 253,
                        "minLength": 1,
                        "nullable": true,
                        "type": "string"
                      },
                      "secretName": {
                        "description": "Override the generated Secret name. Defaults to `{policy}-pgr-{role}`.",
                        "maxLength": 253,
                        "minLength": 1,
                        "nullable": true,
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "secretKey": {
                    "description": "Key within the referenced Secret. Defaults to the role name.\nOnly used with `secretRef`.",
                    "maxLength": 253,
                    "minLength": 1,
                    "nullable": true,
                    "type": "string"
                  },
                  "secretRef": {
                    "description": "Reference to an existing Kubernetes Secret containing the password.\nMutually exclusive with `generate`.",
                    "nullable": true,
                    "properties": {
                      "name": {
                        "description": "Name of the Secret.",
                        "maxLength": 253,
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "name"
                    ],
                    "type": "object"
                  }
                },
                "type": "object"
              },
              "password_valid_until": {
                "description": "Password expiration timestamp (ISO 8601, e.g. \"2025-12-31T00:00:00Z\").",
                "maxLength": 64,
                "nullable": true,
                "type": "string"
              },
              "preserve_undeclared_grants": {
                "default": false,
                "description": "Preserve this role's undeclared in-scope object grants during\nconvergence. Revokes against the role are skipped unless the revoked\nprivileges are explicitly asserted absent (`ensure: absent`).",
                "type": "boolean"
              },
              "replication": {
                "description": "Whether the role may initiate replication connections.",
                "nullable": true,
                "type": "boolean"
              },
              "superuser": {
                "description": "Whether the role bypasses PostgreSQL permission checks as a superuser.",
                "nullable": true,
                "type": "boolean"
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          },
          "maxItems": 1024,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "name"
          ],
          "x-kubernetes-list-type": "map"
        },
        "schemas": {
          "default": [],
          "description": "Schema bindings that expand profiles into concrete roles/grants.\n\nKeyed by `name` so server-side apply merges entries per schema instead\nof replacing the whole list. The API server also rejects duplicate keys.",
          "items": {
            "description": "Associates a PostgreSQL schema with one or more reusable privilege profiles.",
            "properties": {
              "name": {
                "description": "PostgreSQL schema name.",
                "maxLength": 63,
                "minLength": 1,
                "type": "string"
              },
              "owner": {
                "description": "Override default_owner for this schema's default privileges.",
                "maxLength": 63,
                "minLength": 1,
                "nullable": true,
                "type": "string"
              },
              "profiles": {
                "default": [],
                "description": "Profile names to expand for this schema.",
                "items": {
                  "maxLength": 63,
                  "minLength": 1,
                  "type": "string"
                },
                "maxItems": 64,
                "type": "array"
              },
              "role_pattern": {
                "description": "Role naming pattern. Supports `{schema}` and `{profile}` placeholders.\nOverrides the policy pattern; otherwise inherits it, falling back to `\"{schema}-{profile}\"`.",
                "maxLength": 128,
                "minLength": 1,
                "nullable": true,
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          },
          "maxItems": 1024,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "name"
          ],
          "x-kubernetes-list-type": "map"
        },
        "suspend": {
          "default": false,
          "description": "Suspend reconciliation when true. Defaults to false.",
          "type": "boolean"
        }
      },
      "required": [
        "connection"
      ],
      "type": "object"
    },
    "status": {
      "description": "Status of a `PostgresPolicy` resource.",
      "nullable": true,
      "properties": {
        "applied_password_source_versions": {
          "additionalProperties": {
            "type": "string"
          },
          "default": {},
          "description": "Last applied password source version for each password-managed role.",
          "type": "object"
        },
        "change_summary": {
          "description": "Summary of changes applied in the last reconciliation.",
          "nullable": true,
          "properties": {
            "default_privileges_revoked": {
              "default": 0,
              "description": "Number of default privilege revoke steps.",
              "format": "int32",
              "type": "integer"
            },
            "default_privileges_set": {
              "default": 0,
              "description": "Number of default privilege grant steps.",
              "format": "int32",
              "type": "integer"
            },
            "grants_added": {
              "default": 0,
              "description": "Number of object privilege grant steps.",
              "format": "int32",
              "type": "integer"
            },
            "grants_revoked": {
              "default": 0,
              "description": "Number of object privilege revoke steps.",
              "format": "int32",
              "type": "integer"
            },
            "members_added": {
              "default": 0,
              "description": "Number of membership additions.",
              "format": "int32",
              "type": "integer"
            },
            "members_removed": {
              "default": 0,
              "description": "Number of membership removals.",
              "format": "int32",
              "type": "integer"
            },
            "passwords_set": {
              "default": 0,
              "description": "Number of password updates.",
              "format": "int32",
              "type": "integer"
            },
            "roles_altered": {
              "default": 0,
              "description": "Number of role attribute or configuration changes.",
              "format": "int32",
              "type": "integer"
            },
            "roles_created": {
              "default": 0,
              "description": "Number of role creations.",
              "format": "int32",
              "type": "integer"
            },
            "roles_dropped": {
              "default": 0,
              "description": "Number of role drops.",
              "format": "int32",
              "type": "integer"
            },
            "schema_owners_altered": {
              "default": 0,
              "description": "Number of schema ownership changes.",
              "format": "int32",
              "type": "integer"
            },
            "schemas_created": {
              "default": 0,
              "description": "Number of schema creations.",
              "format": "int32",
              "type": "integer"
            },
            "sessions_terminated": {
              "default": 0,
              "description": "Number of session-termination steps.",
              "format": "int32",
              "type": "integer"
            },
            "total": {
              "default": 0,
              "description": "Number of all planned change steps.",
              "format": "int32",
              "type": "integer"
            }
          },
          "type": "object"
        },
        "conditions": {
          "default": [],
          "description": "Standard Kubernetes conditions.",
          "items": {
            "description": "A condition on the `PostgresPolicy` resource.",
            "properties": {
              "last_transition_time": {
                "description": "Last time the condition transitioned.",
                "nullable": true,
                "type": "string"
              },
              "message": {
                "description": "Human-readable message.",
                "nullable": true,
                "type": "string"
              },
              "reason": {
                "description": "Human-readable reason for the condition.",
                "nullable": true,
                "type": "string"
              },
              "status": {
                "description": "Status: \"True\", \"False\", or \"Unknown\".",
                "type": "string"
              },
              "type": {
                "description": "Controller-defined condition type, such as Ready, Reconciling, or Degraded.\nThis is an open vocabulary; consult status guidance for operational meanings.",
                "type": "string"
              }
            },
            "required": [
              "status",
              "type"
            ],
            "type": "object"
          },
          "type": "array"
        },
        "content_digest": {
          "description": "Canonical digest of this policy's own content, computed by exactly the\nsame function as a candidate's `status.contentDigest` (note the wire\nnames differ: this status object serialises snake_case, so the field is\n`status.content_digest` here).\n\nPromotion is recognised by comparing the two. The value is also the\noperator's memory of what the content was on the previous reconcile,\nwhich is how an edited-after-approval promotion is distinguished from a\npolicy that simply has not changed while a candidate is under review.",
          "nullable": true,
          "type": "string"
        },
        "current_plan_ref": {
          "description": "Reference to the current/latest plan for this policy.",
          "nullable": true,
          "properties": {
            "name": {
              "description": "Name of the PostgresPolicyPlan in the same namespace.",
              "type": "string"
            }
          },
          "required": [
            "name"
          ],
          "type": "object"
        },
        "lastHandledReconcileAt": {
          "description": "Last force-reconcile annotation value handled by the operator.",
          "nullable": true,
          "type": "string"
        },
        "last_attempted_generation": {
          "description": "The `.metadata.generation` that was last attempted.",
          "format": "int64",
          "nullable": true,
          "type": "integer"
        },
        "last_error": {
          "description": "Last reconcile error message, if any.",
          "nullable": true,
          "type": "string"
        },
        "last_reconcile_mode": {
          "description": "Controls whether the operator executes changes or only computes plans.",
          "enum": [
            "apply",
            "observe",
            "plan"
          ],
          "nullable": true,
          "type": "string"
        },
        "last_successful_reconcile_time": {
          "description": "ISO 8601 timestamp of the last successful reconciliation.",
          "nullable": true,
          "type": "string"
        },
        "managed_database_identity": {
          "description": "Canonical identity of the managed database target.",
          "nullable": true,
          "type": "string"
        },
        "observed_generation": {
          "description": "The `.metadata.generation` that was last successfully reconciled.",
          "format": "int64",
          "nullable": true,
          "type": "integer"
        },
        "owned_roles": {
          "default": [],
          "description": "Roles claimed by this policy's declared ownership scope.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "owned_schemas": {
          "default": [],
          "description": "Schemas claimed by this policy's declared ownership scope.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "plan_warnings": {
          "default": [],
          "description": "Advisory warnings from the last reconciliation's computed plan — for\nexample adopt-mode schema ownership transfers or an undeclared\n`default_owner`. Populated even when the plan applied cleanly.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "transient_failure_count": {
          "default": 0,
          "description": "Consecutive transient operational failures used for exponential backoff.",
          "format": "int32",
          "type": "integer"
        }
      },
      "type": "object"
    }
  },
  "required": [
    "spec"
  ],
  "title": "PostgresPolicy",
  "type": "object"
}
