Governed substrate for autonomous agents: scoped identity (passports), audited actions, MCP workspace. Infra IPs and secrets redacted for public release. |
||
|---|---|---|
| .. | ||
| .gitignore | ||
| docker-compose.yaml | ||
| penpot.env.example | ||
| README.md | ||
Penpot — GOD CRM design instance
Self-hosted Penpot with "Login with GOD CRM" SSO. One instance
on PROD .128 serves both design domains:
| Domain | Path to penpot |
|---|---|
design.godcrm.ai |
.128 nginx → 127.0.0.1:9011 (direct) |
design.hltrn.cc |
.72 nginx → proxy to .128 (Host rewritten to design.godcrm.ai) |
Live copy runs from /root/penpot on .128; this dir is the version-controlled source.
SSO (OIDC via GOD CRM)
- CRM side:
oidc_clientsrowclient_id=penpot,is_active=1, with both redirect URIs registered so login works from either domain:https://design.hltrn.cc/api/auth/oidc/callbackhttps://design.godcrm.ai/api/auth/oidc/callback
- Penpot side: all OIDC endpoints are set explicitly (see compose) so penpot skips
discovery and always talks to
godcrm.ai(valid cert + live user DB). Same pattern as WorkAdventure (ADR-063 /penpot-oidc-sso-via-crm). PENPOT_PUBLIC_URI=https://design.hltrn.cc, so the OIDC callback lands ondesign.hltrn.ccregardless of which domain starts the flow — both callbacks are whitelisted, so login completes either way.- Verify a domain is live (should return HTTP 200 + a
redirect-uritogodcrm.ai/oauth/authorize):curl -sS -X POST 'https://design.godcrm.ai/api/auth/oidc?provider=oidc' curl -sS -X POST 'https://design.hltrn.cc/api/auth/oidc?provider=oidc'
Deploy
cp penpot.env.example penpot.env # fill real secrets
docker compose --env-file penpot.env up -d
Secrets live only in penpot.env (gitignored). Never inline them in the compose.