Skip to main content

Config Reference (client.json)

The entire deployment is driven by one JSON config validated before anything is created. Validation aggregates all problems in one pass (placeholder CHANGE_ME values, malformed ARNs, unsupported regions/versions) and refuses to synthesize — a wrong config fails in seconds, not mid-deploy. Secret values never appear here; secrets are always referenced by Secrets Manager ARN.

Identity & placement​

FieldProvided byFormat / rule
accountClient12-digit AWS account ID
regionClientMust be in the EKS Auto Mode allow-list (see prerequisites §1)

Networking (imported, never created)​

FieldProvided byFormat / rule
vpcIdClientvpc-…, must exist in region
privateSubnetIdsClient≥ 2 distinct subnet IDs in distinct AZs, NAT egress required
publicSubnetIdsClientRequired (≥ 2) only when ingressPublic: true
extraSecurityGroupIdsClient≥ 1 SG the client owns — the app never creates security groups

DNS & cluster shape​

FieldProvided byFormat / rule
hostedZoneIdClientRoute53 public zone in the same account
domainClientFQDN; the zone's name or a subdomain of it (checked against the actual zone)
k8sVersionClient (or default)1.31–1.36; chart floor is 1.27
adminRoleArnsClient≥ 1 IAM role ARN granted cluster admin via access entries
ingressPublicClient decisionDefault true → internet-facing NLB restricted to allowedCidrs. Set false for an internal NLB (VPN/peering only), where no allowlist is needed
allowedCidrsClientPUBLIC egress CIDRs allowed to reach the ingress, enforced as NLB security-group rules. Required when the ingress is public — an empty list fails the deploy rather than allowing everything. 0.0.0.0/0 and private/RFC1918 ranges are both rejected
clusterEndpointPublicAccessClient decisionDefault true; false = deploys must run inside your network
kmsKeyArnClient (optional)CMK for EKS secrets envelope encryption (control-plane, not the app key)
iamPermissionsBoundaryArnClient (optional)Attached to every role the app creates

Registry, app config & app secrets​

FieldProvided byFormat / rule
chartSourceAgreementghcr (default) or marketplace — which build of the chart is installed. Must match the bundle you were given; the deployment names the mismatch and the fix
ghcrSecretArnClient stores, vendor issues tokenSecrets Manager ARN whose value is a complete .dockerconfigjson. Required for ghcr; ignored for marketplace, whose images are pulled with the nodes' IAM role (your account must be subscribed to the listing)
coreEnv / backendEnvClientNon-secret env values merged into each service's environment (e.g. SES_FROM_EMAIL, SES_ROLE_ARN, S3_REGION, CONTROL_PLANE_URL, GITHUB_APP_ID). A plain key/value map — validation rejects secret-looking keys, because anything here is plaintext in config and in the CloudFormation template

There is no .env file. Every value reaches the apps through one path — the environment (envFrom) — so there are no file-vs-env precedence rules to reason about.

AWS credentials are not a client input. The deployment creates an IAM user, access key, and assumable role per service and injects them automatically (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_ROLE_ARN for core; those plus KMS_ACCESS_KEY_ID/KMS_SECRET_ACCESS_KEY/KMS_ROLE_ARN/KMS_REGION/KMS_SYMMETRIC_KEY_ID for the backend). Do not put them in coreEnv/backendEnv — the generated values win on collision.

Frontend​

FieldProvided byFormat / rule
recaptchaSiteKeyClient (Google console)Public site key, injected into the frontend at runtime. Its allowed-domains list must cover your domain, or the widget renders but every submit fails verification
recaptchaSecretKeyClient (Google console)Private key, delivered to the backend. Must be set together with the site key — a site key alone fails every verification. Note: this is the one secret stored in plaintext config (and therefore in the CloudFormation template); it is a deliberate exception so the reCAPTCHA pair stays a single obvious input
recaptchaDisabledClient decisiontrue switches reCAPTCHA off in both the backend and the frontend

Set either the key pair or recaptchaDisabled: true — validation rejects both together and neither. reCAPTCHA is on by default, so an install with no keys and no opt-out would come up with a sign-in page that always fails.

Org seeding (optional with ghcr, required with marketplace)​

FieldProvided byFormat / rule
seedOrgEmailClientAdmin email; the org ID becomes the domain after @ (lowercased). Public email domains (gmail, outlook, …) are rejected. When set, the backend creates the org + admin user on first start; the generated password lands in k8s Secret openbox-seed-admin (retrieval command in stack outputs). The password is not pre-expired — change it after signing in

Application KMS (created automatically — no config)​

The deployment always creates the backend's symmetric application key: the backend cannot run without one, so it is not a client input. Alias is install-scoped (alias/openbox-backend-<your-domain>), rotation off, RETAIN on stack delete so encrypted data outlives the stack.

No key-policy grants are configured: a CDK-created key carries the account-root statement, so your backend's IAM principal can use it as long as its own IAM policy allows kms:*. If your SCPs require explicit key-policy grants instead, add them out-of-band against the exported ARN.

The key ARN is a stack output; put it in the backend env file as KMS_SYMMETRIC_KEY_ID (with KMS_REGION = deploy region).

License​

FieldProvided byFormat / rule
licenseSecretArnClient stores, vendor issuesARN of the raw license token. Required unless poc
licenseTenantIdVendorRequired unless poc
licenseControlPlaneUrlVendorhttps:// URL; required unless poc or licenseMode: "airgap"
licenseModeAgreementconnected (default) or airgap
pocAgreementtrue waives the license gate and uses the evaluation chart profile. Not available with chartSource: "marketplace"

OPA policy bundle (bucket created automatically)​

The deployment always creates the policy-bundle bucket (openbox-opa-policies-<account>-<region>, versioned, RETAIN) and the IAM role OPA assumes to read it. Authentication is IRSA / web identity — there are no static S3 keys to issue, store, or rotate.

FieldProvided byFormat / rule
opaBundleEnabledOperator decisionDefault false. The bucket starts empty, and pointing OPA at a missing bundle.tar.gz leaves it with no policy while every probe still looks healthy — so OPA runs on its built-in policy until you upload a bundle (upload command is a stack output) and set this to true.
Nothing for the client to create — backend wiring pending

On the CDK path the bucket and OPA's read role are created for you; the client does not pre-create S3. The backend, however, builds the policy bundle itself on every policy or behavior-rule save and must be able to write it to this bucket. That wiring (a backend write role and the chart's global.policyBundle) is not in the CDK yet — until it ships, confirm with us before relying on governance policies on a CDK install.

What the deployment outputs back to you​

Stack outputs after a successful run: the service URLs, the OPA bundle bucket name and its upload command (frontend, API, identity, OPA, core), the ingress NLB hostname, the backend KMS key ARN (if created), and the command to read the generated Keycloak admin password from the cluster. Passwords for bundled Postgres/Redis/Keycloak are generated in-cluster and never leave it.