feat(dev): local docker-compose stack
Adds dev/docker-compose.yml + dev/keycloak/realm-export.json + dev/README.md and Makefile targets so a developer can: make dev-up and get Keycloak 26 on :8080 with the breakpilot-dev realm pre-imported, plus pg-app (:5432), Redis (:6379), Mongo (:27017), and MinIO (:9000 + :9001). Seed users: test@breakpilot.dev / test — IT_ADMIN of tenant 'acme' admin@breakpilot.dev / admin — BREAKPILOT_ADMIN (platform staff) Realm includes a dev-portal public PKCE client (redirect URIs cover http://localhost:3000/* and http://*.localhost:3000/* so subdomain routing works in dev) and a dev-tenant-registry bearer-only client. Protocol mappers project tenant_id, tenant_slug, org_roles, products, plan, and tenant_status into every issued JWT — the contract portal + tenant-registry expect in prod, fronted by Keycloak attributes today. dev/ lives in orca-platform because this repo already documents the production topology that this compose mirrors. INFRASTRUCTURE.md §1 sets dev as 'docker-compose on developer laptops' — this is that compose. Refs: M0.1+ (precondition for local-dev work on tenant-registry / portal)
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
{
|
||||
"realm": "breakpilot-dev",
|
||||
"enabled": true,
|
||||
"displayName": "Breakpilot (dev)",
|
||||
"registrationAllowed": false,
|
||||
"loginWithEmailAllowed": true,
|
||||
"duplicateEmailsAllowed": false,
|
||||
"resetPasswordAllowed": true,
|
||||
"editUsernameAllowed": false,
|
||||
"bruteForceProtected": true,
|
||||
"accessTokenLifespan": 900,
|
||||
"ssoSessionIdleTimeout": 3600,
|
||||
"ssoSessionMaxLifespan": 36000,
|
||||
"internationalizationEnabled": false,
|
||||
"defaultSignatureAlgorithm": "RS256",
|
||||
"organizationsEnabled": true,
|
||||
|
||||
"roles": {
|
||||
"realm": [
|
||||
{ "name": "BREAKPILOT_ADMIN", "description": "Platform staff: full backstage access" },
|
||||
{ "name": "SUPPORT_ENGINEER", "description": "Platform staff: tenant impersonation + read" },
|
||||
{ "name": "SALES_REP", "description": "Platform staff: demo-tenant access only" }
|
||||
]
|
||||
},
|
||||
|
||||
"groups": [
|
||||
{
|
||||
"name": "IT_ADMIN",
|
||||
"path": "/IT_ADMIN",
|
||||
"attributes": { "org_role": ["IT_ADMIN"] }
|
||||
},
|
||||
{
|
||||
"name": "CXO",
|
||||
"path": "/CXO",
|
||||
"attributes": { "org_role": ["CXO"] }
|
||||
},
|
||||
{
|
||||
"name": "USER",
|
||||
"path": "/USER",
|
||||
"attributes": { "org_role": ["USER"] }
|
||||
}
|
||||
],
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "test@breakpilot.dev",
|
||||
"email": "test@breakpilot.dev",
|
||||
"emailVerified": true,
|
||||
"firstName": "Test",
|
||||
"lastName": "Acme",
|
||||
"enabled": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "test",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"tenant_id": ["00000000-0000-0000-0000-000000000001"],
|
||||
"tenant_slug": ["acme"],
|
||||
"org_roles": ["IT_ADMIN"],
|
||||
"products": ["certifai", "compliance"],
|
||||
"plan": ["professional"],
|
||||
"tenant_status": ["active"]
|
||||
},
|
||||
"groups": ["/IT_ADMIN"]
|
||||
},
|
||||
{
|
||||
"username": "admin@breakpilot.dev",
|
||||
"email": "admin@breakpilot.dev",
|
||||
"emailVerified": true,
|
||||
"firstName": "Platform",
|
||||
"lastName": "Admin",
|
||||
"enabled": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "admin",
|
||||
"temporary": false
|
||||
}
|
||||
],
|
||||
"realmRoles": ["BREAKPILOT_ADMIN"]
|
||||
}
|
||||
],
|
||||
|
||||
"clients": [
|
||||
{
|
||||
"clientId": "dev-portal",
|
||||
"name": "Customer Portal (dev)",
|
||||
"enabled": true,
|
||||
"publicClient": true,
|
||||
"standardFlowEnabled": true,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"implicitFlowEnabled": false,
|
||||
"serviceAccountsEnabled": false,
|
||||
"rootUrl": "http://localhost:3000",
|
||||
"baseUrl": "http://localhost:3000",
|
||||
"redirectUris": [
|
||||
"http://localhost:3000/*",
|
||||
"http://acme.localhost:3000/*",
|
||||
"http://demo.localhost:3000/*"
|
||||
],
|
||||
"webOrigins": ["+"],
|
||||
"attributes": {
|
||||
"pkce.code.challenge.method": "S256",
|
||||
"post.logout.redirect.uris": "http://localhost:3000/*##http://*.localhost:3000/*"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"name": "tenant_id-mapper",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"config": {
|
||||
"user.attribute": "tenant_id",
|
||||
"claim.name": "tenant_id",
|
||||
"jsonType.label": "String",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"userinfo.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tenant_slug-mapper",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"config": {
|
||||
"user.attribute": "tenant_slug",
|
||||
"claim.name": "tenant_slug",
|
||||
"jsonType.label": "String",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"userinfo.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "org_roles-mapper",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"config": {
|
||||
"user.attribute": "org_roles",
|
||||
"claim.name": "org_roles",
|
||||
"jsonType.label": "String",
|
||||
"multivalued": "true",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "products-mapper",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"config": {
|
||||
"user.attribute": "products",
|
||||
"claim.name": "products",
|
||||
"jsonType.label": "String",
|
||||
"multivalued": "true",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "plan-mapper",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"config": {
|
||||
"user.attribute": "plan",
|
||||
"claim.name": "plan",
|
||||
"jsonType.label": "String",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tenant_status-mapper",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-attribute-mapper",
|
||||
"config": {
|
||||
"user.attribute": "tenant_status",
|
||||
"claim.name": "tenant_status",
|
||||
"jsonType.label": "String",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"clientId": "dev-tenant-registry",
|
||||
"name": "Tenant Registry (dev)",
|
||||
"enabled": true,
|
||||
"bearerOnly": true,
|
||||
"publicClient": false,
|
||||
"standardFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"serviceAccountsEnabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user