{"id":42946242,"url":"https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator","last_synced_at":"2026-01-30T20:36:28.208Z","repository":{"id":320179322,"uuid":"1072696443","full_name":"cloudnative-pg/postgres-keycloak-oauth-validator","owner":"cloudnative-pg","description":"PostgreSQL OAuth Validator for Keycloak","archived":false,"fork":false,"pushed_at":"2026-01-22T05:52:39.000Z","size":145,"stargazers_count":14,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-30T17:49:41.964Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudnative-pg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-09T05:00:24.000Z","updated_at":"2026-01-27T05:01:27.000Z","dependencies_parsed_at":"2025-10-22T12:28:30.940Z","dependency_job_id":"15c43639-6db2-4a39-9b2a-b11a34770ccb","html_url":"https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator","commit_stats":null,"previous_names":["cloudnative-pg/postgres-keycloak-oauth-validator"],"tags_count":0,"template":false,"template_full_name":"cloudnative-pg/cnpg-template","purl":"pkg:github/cloudnative-pg/postgres-keycloak-oauth-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudnative-pg%2Fpostgres-keycloak-oauth-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudnative-pg%2Fpostgres-keycloak-oauth-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudnative-pg%2Fpostgres-keycloak-oauth-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudnative-pg%2Fpostgres-keycloak-oauth-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudnative-pg","download_url":"https://codeload.github.com/cloudnative-pg/postgres-keycloak-oauth-validator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudnative-pg%2Fpostgres-keycloak-oauth-validator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28918552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T20:25:28.696Z","status":"ssl_error","status_checked_at":"2026-01-30T20:25:13.426Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-30T20:36:27.555Z","updated_at":"2026-01-30T20:36:28.197Z","avatar_url":"https://github.com/cloudnative-pg.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CloudNativePG](./logo/cloudnativepg.png)](https://cloudnative-pg.io/)\n\n# PostgreSQL OAuth Validator for Keycloak\n\n**EXPERIMENTAL**\n\n**Requires**: PostgreSQL 18+\n\nThis module enables PostgreSQL 18 to delegate authorization decisions to Keycloak using OAuth tokens, leveraging Keycloak Authorization Services for fine-grained, token-based access control.\nIt sends a permission request to Keycloak's token endpoint using `grant_type=urn:ietf:params:oauth:grant-type:uma-ticket` and expects a decision response (`response_mode=decision`), which is a Keycloak-specific extension.\nIt is designed for use with CloudNativePG, allowing database role elevation to be controlled by Keycloak policies.\n\n---\n\n## Features\n\n- **Keycloak-based authorization for PostgreSQL roles**\n  - Delegates database role elevation decisions to Keycloak Authorization Services using OAuth tokens.\n- **Permission string construction**\n  - Builds permission strings as `\u003cresource_name\u003e#\u003cscope\u003e` and sends permission requests to Keycloak's token endpoint (`grant_type=urn:ietf:params:oauth:grant-type:uma-ticket`, `response_mode=decision`).\n- **Configurable via PostgreSQL GUC parameters**\n  - All integration settings (endpoints, resource names, timeouts, debug, etc.) are controlled via GUCs.\n- **Secure HTTP communication**\n  - Uses libcurl for HTTP requests with configurable timeouts and safe logging.\n- **Optional JWT issuer verification**\n  - Can verify the `iss` claim in JWT tokens for additional security.\n\n---\n\n## Example: CloudNativePG Configuration\n\n```yaml\napiVersion: postgresql.cnpg.io/v1\nkind: Cluster\nmetadata:\n  name: pg-oauth\nspec:\n  imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie\n  instances: 1\n\n  postgresql:\n    extensions:\n      - name: keycloak-oauth-validator\n        ld_library_path:\n          - system\n        image:\n          reference: ghcr.io/cloudnative-pg/postgres-keycloak-oauth-validator-testing:18-dev-trixie\n    parameters:\n      oauth_validator_libraries: \"kc_validator\"\n      kc.token_endpoint: \"https://\u003ckeycloak\u003e/realms/\u003crealm\u003e/protocol/openid-connect/token\"\n      kc.audience: \"postgres-resource\"\n      kc.resource_name: \"appdb\"       # Resource name in Keycloak\n      kc.client_id: \"postgres-resource\"\n      kc.http_timeout_ms: \"2000\"\n      kc.expected_issuer: \"https://\u003ckeycloak\u003e/realms/\u003crealm\u003e\"\n      kc.debug: \"on\"\n      kc.log_body: \"on\"\n      log_min_messages: \"debug1\"\n    pg_hba:\n      - host all all 0.0.0.0/0 oauth issuer=\"https://\u003ckeycloak\u003e/realms/\u003crealm\u003e\" scope=db_access validator=\"kc_validator\" delegate_ident_mapping=1\n```\n\nFor a full example, see `examples/cnpg/cluster.yaml`.\n\n---\n\n## Keycloak Configuration Steps\n\n1. **Realm**\n   Create or use an existing realm (e.g., `demo`).\n\n2. **Resource Server Client** (`kc.audience`)\n   Create a client for Authorization Services (e.g., `postgres-resource`).\n   Enable Authorization Services and add scopes as needed (e.g., `app_readonly`, `app_readwrite`).\n\n3. **Validator Client** (`kc.client_id`)\n   A client allowed to call the token endpoint for permission decisions.\n\n4. **Resource \u0026 Permission**\n   Resource name: `\u003ckc.resource_name\u003e` (e.g., `appdb`).\n   Scope name: `\u003cscope\u003e` (e.g., `app_readonly`, `app_readwrite`).\n   Permission name: `\u003cresource_name\u003e#\u003cscope\u003e` (e.g., `appdb#app_readonly`).\n   Create a permission for each database role you want to allow (e.g., DB role `app_readonly` maps to Keycloak scope `app_readonly`, permission name `appdb#app_readonly`).\n\n5. **Policies**\n   Attach policies to permissions so that only intended users can access specific scopes.\n\n6. **Issuer Verification (optional)**\n   Set `kc.expected_issuer` to your realm's issuer URL (e.g., `https://\u003ckeycloak\u003e/realms/\u003crealm\u003e`).\n\n---\n\n## Quick Start with psql and Device Flow\n\nYou can quickly test the validator using Keycloak's Device Flow and psql:\n\n1. **Connect to PostgreSQL using psql with OAuth parameters:**\n\n    ```bash\n    psql \"host=\u003ckeycloak\u003e \\\n        user=app_readonly \\\n        dbname=appdb \\\n        oauth_issuer=https://\u003ckeycloak\u003e/realms/demo \\\n        oauth_client_id=appA \\\n        oauth_client_secret=\u003cclient secret\u003e \\\n        oauth_scope='db_access'\"\n    ```\n\n    When you run this command, psql will display a Device Authorization URL and a device code.\n\n2. **Authenticate via browser:**\n\n    - Open the displayed URL in your browser.\n    - Enter the device code shown by psql.\n    - Log in with your Keycloak username and password.\n\n    Once authentication is complete, psql will automatically obtain an access token and connect to the database.\n\n\u003e Note:\nThe DB role (`app_readonly`) should match the Keycloak scope name.\nThe validator will request permission `\u003cresource_name\u003e#\u003cscope\u003e` (e.g., `appdb#app_readonly`) from Keycloak Authorization Services.\n\n---\n\n## Build Instructions\n\n### Local\n\nTo compile the extension is required [meson](https://mesonbuild.com/) tool.\n\n```bash\nmeson setup build\nmeson compile -C build\n```\nThe extension will be located inside the `build/` directory, that was\ncreated during the setup process.\n\n### Docker\n\nA simple possibility is to build the image using a plain docker build\ncommand:\n\n```bash\ndocker build -t pg-kc-validator -f docker/Dockerfile .\n```\n\nTo have all the possible labels, annotations, SBOMS, etc. the\nimage can be built using Docker Bake:\n\n```bash\ndocker buildx bake\n```\n\n---\n\n## Security Notes\n\n- Do not use self-signed certificates (server.crt) in production; always use a trusted CA.\n- Enable `kc.log_body` only for debugging; keep it `off` in production.\n- Place CA certificates in `/usr/local/share/ca-certificates/` and run `update-ca-certificates` in your Docker image.\n\n---\n\n## License\n\nApache-2.0. See `LICENSE`.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudnative-pg%2Fpostgres-keycloak-oauth-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudnative-pg%2Fpostgres-keycloak-oauth-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudnative-pg%2Fpostgres-keycloak-oauth-validator/lists"}