Skip to main content

Security Hardening

AI-in-a-Box ships with development-friendly defaults and generated local secrets. Treat make bootstrap as a dev convenience, not a production key management process.

Production Checklist

1. Generate Real Secrets

Run make bootstrap for local development. For production, provide strong values from your secret manager for at least:

SecretPurpose
POSTGRES_PASSWORDMain PostgreSQL cluster.
MINIO_ROOT_PASSWORDObject storage.
REDIS_PASSWORDRedis.
KEYCLOAK_ADMIN_PASSWORDKeycloak admin console.
AUDIT_SIGNING_KEYAudit row and turn-envelope signing.
AIBOX_PRINCIPAL_KEYSGateway signed principal headers.
AIBOX_CAPTOKEN_KEYSTurn capability tokens.
SECRETS_MASTER_KEYPer-user secret encryption.
SERVICE_*_CLIENT_SECRETPer-service Keycloak confidential clients.
DIFY_* secretsDify database, admin, plugin, and sandbox secrets.

The placeholder aibox-audit-signing-key-change-me is rejected by the audit service. Use a minimum 32-character signing key and retain old versions when rotating.

2. Enable Gateway Authentication

Set gateway auth in deploy/config/gateway/config.yaml:

auth:
enabled: true
jwks_url: http://keycloak:8080/realms/aibox/protocol/openid-connect/certs
issuer: http://your-domain/realms/aibox

The gateway validates JWTs, strips inbound identity headers, derives tenant and user headers, signs X-Aibox-Principal, and mints per-turn CapTokens for downstream services.

3. Use HTTPS and Correct Issuers

Terminate TLS in front of the public gateway and Keycloak endpoints. Ensure the JWT issuer configured in the gateway exactly matches the issuer in tokens, including scheme, hostname, and port.

In Keycloak, set realm SSL requirements and client redirect URIs to your production domains. Remove localhost redirect URIs from production clients.

4. Keep Password Grants Disabled

The realm import sets directAccessGrantsEnabled=false for the frontend client. Keep it disabled outside isolated dev testing. Use authorization code with PKCE for browser users and confidential clients for service or operator automation.

5. Restrict Internal Ports

Do not expose internal service ports publicly. Public ingress should normally be limited to the frontend/gateway and your identity provider endpoint.

Internal services include agent-runtime, guardrail, memory, inference-router, knowledge, sandbox, observability, audit, Qdrant, MinIO, Redis, and PostgreSQL.

6. Rotate Service Client Secrets

Internal service-to-service calls use short-lived Keycloak tokens from per-service confidential clients. Rotate each SERVICE_*_CLIENT_SECRET in Keycloak and in your deployment secrets, then restart only affected services.

There is no shared-bearer fallback.

7. Review Guardrails

Review deploy/config/guardrail/constitution.yaml and add organization-specific principles and blocked topics. Enable stricter scanner profiles for regulated or externally exposed deployments.

Remember that input Constitutional AI is disabled by default for latency; output Constitutional AI is enabled when the global constitution toggle is enabled.

8. Protect Receipts and Audit Data

Audit rows are append-only at the database layer and chained by tenant. Turn envelopes include Merkle roots and signatures, but proof verification depends on retaining the relevant signing keys by version.

Run verification after backup restore or suspicious operational events:

curl "http://localhost:8080/v1/admin/audit/verify?tenant_id=default" \
-H "Authorization: Bearer $TOKEN"

9. Configure Observability Credentials

Replace development Langfuse keys and review who can access observability data. Prompts, completions, tool inputs, and trace metadata may contain sensitive tenant information.

Troubleshooting

ProblemCheck
Token validation failsGateway issuer must match the token issuer exactly.
Downstream service rejects identityVerify AIBOX_PRINCIPAL_KEYS are shared between gateway and services.
Turn operations failVerify AIBOX_CAPTOKEN_KEYS are shared by turn-aware services.
Audit service fails on startupReplace the placeholder AUDIT_SIGNING_KEY.
API scripts cannot get a tokenPassword grants are disabled by default; use a supported OAuth flow or confidential client.