7e7e9d741bba3cdf3655c8e781191b8b69ba19b1
The orchestrator is its own client so the exchanged token carries azp = the agent doing the asking. It is granted two optional scopes — the Catalogue agent's audience, and llm-proxy-audience because it has to reason — and no domain audience at all. Every mcp-* and *-api scope it could request comes back Invalid scopes, which is what makes 'the orchestrator holds nothing' a property of the realm rather than a line in a prompt. Note for the next client added by hand: CLIENT.DESCRIPTION is varchar(255), and a longer one crash-loops the import with 'value too long' rather than a validation message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pm-keycloak
Keycloak deployment with declarative realm configuration via keycloak-config-cli.
Stack
- Keycloak 26.5.4 — identity and access management
- PostgreSQL 16 — persistent storage
- keycloak-config-cli 6.5.0 — declarative realm configuration
Installation
Prerequisites
- Docker and Docker Compose
Setup
cd compose
cp .env.example .env
Edit .env with your credentials:
COMPOSE_PROJECT_NAME=pm-keycloak
KC_DB_PASSWORD=<your-db-password>
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=<your-admin-password>
Start
docker compose up -d
Keycloak is available at http://localhost:8080.
keycloak-config-cli runs once at startup, applies all realm configuration files, then exits. This is expected behavior.
Configuration
Realm configuration files live in compose/keycloak-config/. Each .yaml file maps to one realm.
Apply configuration changes
After editing a realm file:
docker compose run --rm keycloak-config-cli
File structure
compose/keycloak-config/
├── master-realm.yaml # minimal patch of the master realm
└── demo-realm.yaml # example realm with roles and clients
Managed mode
IMPORT_MANAGED_REALM: full is set, meaning keycloak-config-cli is the source of truth for each realm it manages. Anything not declared in a YAML file will be removed from Keycloak on the next apply.
Description
Languages
Markdown
100%