Skip to main content

Configuration reference

This page is for operators. It lists the environment variables the API reads when it starts. You can also put them in a .env file in the API's working directory.

Single sign-on, email, Slack, workflow and risk settings live in their own YAML files. The settings below only give their paths.

SettingPurposeTypeDefaultExample
CCF_AGENT_INSTANCE_ONESHOT_RETENTIONHow long a one-shot agent instance (daemon=false) can go unseen before the prune job deletes it. (new in 0.21)duration24hCCF_AGENT_INSTANCE_ONESHOT_RETENTION=48h
CCF_AGENT_INSTANCE_PRUNE_ENABLEDSchedules the job that prunes stale agent instances. It runs on the background worker, so it also needs CCF_WORKER_ENABLED. (new in 0.21)booltrueCCF_AGENT_INSTANCE_PRUNE_ENABLED=false
CCF_AGENT_INSTANCE_PRUNE_SCHEDULEWhen the agent instance prune job runs, as a six-field cron expression with seconds first. The job runs at most once an hour, whatever the schedule. (new in 0.21)string0 17 * * * *CCF_AGENT_INSTANCE_PRUNE_SCHEDULE="0 30 * * * *"
CCF_AGENT_INSTANCE_RETENTIONHow long a daemon agent instance can go unseen before the prune job deletes it. (new in 0.21)duration720hCCF_AGENT_INSTANCE_RETENTION=336h
CCF_AGENT_INSTANCE_STALE_AFTERHow recently an agent instance must have sent a heartbeat or a report to count as fresh. (new in 0.21)duration10mCCF_AGENT_INSTANCE_STALE_AFTER=15m
CCF_AGENT_MAX_INSTANCESThe most instances one agent can have that aren't due for pruning. At the cap, a new instance replaces the oldest stale one; when every instance is fresh, a report from a new instance gets 409 Conflict. (new in 0.21)int500CCF_AGENT_MAX_INSTANCES=1000
CCF_AI_API_KEYThe API key for the AI provider that generates dashboard suggestions. Treat it as a secret.stringnoneCCF_AI_API_KEY=<your provider API key>
CCF_AI_BASE_URLOverrides the AI provider's API address, for example to go through a proxy. Empty uses the provider's default.stringnoneCCF_AI_BASE_URL=https://llm-proxy.example.com
CCF_AI_ENABLEDTurns on AI-generated dashboard suggestions, which propose evidence filters for the controls of a system security plan.boolfalseCCF_AI_ENABLED=true
CCF_AI_MAX_CALLS_PER_RUNThe most model calls one suggestion run may plan. A run that would need more is refused. 0 means no limit.int0CCF_AI_MAX_CALLS_PER_RUN=100
CCF_AI_MAX_CONTROLS_PER_CHUNKHow many controls go into one model call of a suggestion run.int40CCF_AI_MAX_CONTROLS_PER_CHUNK=20
CCF_AI_MAX_LABEL_SETS_PER_CHUNKHow many evidence label sets go into one model call of a suggestion run.int200CCF_AI_MAX_LABEL_SETS_PER_CHUNK=100
CCF_AI_MAX_SUGGESTIONS_PER_RUNThe most suggestions one run stores. Further suggestions from the run are dropped.int500CCF_AI_MAX_SUGGESTIONS_PER_RUN=200
CCF_AI_MODELThe model that generates dashboard suggestions.stringclaude-opus-4-8CCF_AI_MODEL=claude-opus-4-8
CCF_AI_PROVIDERThe AI provider. anthropic is the only supported value.stringanthropicCCF_AI_PROVIDER=anthropic
CCF_AI_QUEUE_WORKERSHow many suggestion jobs the background worker runs at once.int4CCF_AI_QUEUE_WORKERS=2
CCF_AI_REQUEST_TIMEOUTHow long one model call may take.duration120sCCF_AI_REQUEST_TIMEOUT=300s
CCF_API_ALLOWED_ORIGINSThe origins allowed to call the API from a browser (CORS), comma separated. Set it to the address of your UI.listhttp://localhost:3000CCF_API_ALLOWED_ORIGINS=https://ccf.example.com,https://ccf-staging.example.com
CCF_APP_PORTThe address the API listens on. A bare port such as 8080 is read as :8080.string:8080CCF_APP_PORT=:8443
CCF_ARTIFACT_MAX_BYTESThe largest policy evaluation artifact an agent can upload, in bytes.int16777216 (16 MiB)CCF_ARTIFACT_MAX_BYTES=33554432
CCF_ARTIFACT_MAX_CONCURRENTHow many artifact uploads the API stores at once. Further uploads wait briefly for a slot, then get 429 Too Many Requests.int8CCF_ARTIFACT_MAX_CONCURRENT=16
CCF_AUTHZ_CACHE_TTLHow long the authzen driver caches each decision. Empty, 0 or an invalid value turns the cache off.duration0 (off)CCF_AUTHZ_CACHE_TTL=5s
CCF_AUTHZ_CEDAR_POLICY_DIRA directory of your own .cedar policy files, added to the bundled role policies. Only the cedar driver reads it.stringnoneCCF_AUTHZ_CEDAR_POLICY_DIR=/etc/ccf/policies
CCF_AUTHZ_DRIVERThe authorization engine. builtin allows every signed-in user and keeps administration to admins; cedar enforces the bundled roles; authzen asks a remote AuthZen policy decision point. See Authentication and permissions.stringbuiltinCCF_AUTHZ_DRIVER=cedar
CCF_AUTHZ_ENDPOINTThe evaluation URL of the remote policy decision point. Only the authzen driver reads it.stringnoneCCF_AUTHZ_ENDPOINT=https://pdp.example.com/access/v1/evaluation
CCF_AUTHZ_FAIL_MODEWhat happens when the policy decision point can't be reached. closed denies the request, open allows it; any other value is read as closed.stringclosedCCF_AUTHZ_FAIL_MODE=closed
CCF_AUTHZ_ROLE_ASSIGNMENTSThe file that assigns roles to users, groups and agents. Only the cedar driver reads it; a missing file authorizes agents only.stringauthz-roles.yamlCCF_AUTHZ_ROLE_ASSIGNMENTS=/etc/ccf/authz-roles.yaml
CCF_DB_CONNECTIONThe PostgreSQL connection string.stringrequiredCCF_DB_CONNECTION="host=db user=ccf dbname=ccf port=5432 sslmode=require"
CCF_DB_DEBUGLogs every SQL statement. The --debug flag sets it too.boolfalseCCF_DB_DEBUG=true
CCF_DB_DRIVERThe database driver. postgres is the only supported value.stringrequiredCCF_DB_DRIVER=postgres
CCF_DIGEST_ENABLEDSchedules the digest emails.booltrueCCF_DIGEST_ENABLED=false
CCF_DIGEST_SCHEDULEWhen the digest emails go out, as a cron expression or a descriptor such as @daily.string@weeklyCCF_DIGEST_SCHEDULE=@daily
CCF_EMAIL_CONFIGThe path of the email configuration file. When the file can't be loaded, the API doesn't send email.stringemail.yamlCCF_EMAIL_CONFIG=/etc/ccf/email.yaml
CCF_ENVIRONMENTThe deployment environment. local and development let the sign-in cookie work over plain HTTP; anything else, including production, marks it Secure.stringproductionCCF_ENVIRONMENT=development
CCF_EVIDENCE_DEFAULT_EXPIRY_MONTHSHow many months evidence stays valid when it doesn't set its own expiry. Values below 1 are read as 1.int1CCF_EVIDENCE_DEFAULT_EXPIRY_MONTHS=3
CCF_EVIDENCE_REQUIRE_SUBJECTWhat the API does with agent evidence that has no subject: off accepts it, warn accepts it and logs a warning, enforce rejects it. (new in 0.21)stringoffCCF_EVIDENCE_REQUIRE_SUBJECT=warn
CCF_JWT_PRIVATE_KEYThe path of the PEM file with the RSA private key that signs tokens. When both key paths are set, the API creates the key files if they don't exist and loads them. When either is unset, it generates a new key pair at each start, so tokens don't survive a restart.stringnoneCCF_JWT_PRIVATE_KEY=/etc/ccf/jwt/private.pem
CCF_JWT_PUBLIC_KEYThe path of the PEM file with the RSA public key that verifies tokens. See CCF_JWT_PRIVATE_KEY.stringnoneCCF_JWT_PUBLIC_KEY=/etc/ccf/jwt/public.pem
CCF_JWT_SECRETA shared secret the API reads at startup and warns about when it's unset. Tokens are signed with the RSA keys, not with this secret.stringchange-meCCF_JWT_SECRET=<a long random string>
CCF_MANUAL_EVIDENCE_REQUIRE_SUBJECTRequires evidence that users submit by hand to name a subject. (new in 0.21)boolfalseCCF_MANUAL_EVIDENCE_REQUIRE_SUBJECT=true
CCF_METRICS_ENABLEDStarts the Prometheus metrics server.booltrueCCF_METRICS_ENABLED=false
CCF_METRICS_PORTThe address the metrics server listens on.string:9090CCF_METRICS_PORT=:9091
CCF_PLAYBACK_ENABLEDServes POST /api/playback/evaluate, which runs a caller's Rego policy against a caller's input inside the API.booltrueCCF_PLAYBACK_ENABLED=false
CCF_PLAYBACK_MAX_BYTESThe largest playback request body, in bytes.int2097152 (2 MiB)CCF_PLAYBACK_MAX_BYTES=4194304
CCF_PLAYBACK_MAX_CONCURRENTHow many playback evaluations run at once across all callers. Further requests get 429 Too Many Requests.int4CCF_PLAYBACK_MAX_CONCURRENT=8
CCF_PLAYBACK_TIMEOUTHow long one playback evaluation may take.duration5sCCF_PLAYBACK_TIMEOUT=10s
CCF_PPROF_ENABLEDStarts the Go pprof profiling server. Don't expose it publicly.boolfalseCCF_PPROF_ENABLED=true
CCF_PPROF_PORTThe address the pprof server listens on. A bare port such as 6060 is read as :6060.string:6060CCF_PPROF_PORT=127.0.0.1:6060
CCF_RISK_CONFIGThe path of the risk configuration file, which turns on and schedules the risk jobs such as review reminders. When the file is invalid, every risk job is off.stringrisk.yamlCCF_RISK_CONFIG=/etc/ccf/risk.yaml
CCF_SLACK_CONFIGThe path of the Slack configuration file. When the file can't be loaded, the Slack integration is off.stringslack.yamlCCF_SLACK_CONFIG=/etc/ccf/slack.yaml
CCF_SSO_CONFIGThe path of the single sign-on (SSO) configuration file. When the file can't be loaded, SSO is off.stringsso.yamlCCF_SSO_CONFIG=/etc/ccf/sso.yaml
CCF_STRICT_DISABLE_PUBLIC_AGENT_ENDPOINTSRequires a token on agent heartbeats, evidence and playback. By default these endpoints also accept requests without one.boolfalseCCF_STRICT_DISABLE_PUBLIC_AGENT_ENDPOINTS=true
CCF_USE_DEV_LOGGERLogs in a human-readable development format instead of JSON.boolfalseCCF_USE_DEV_LOGGER=true
CCF_WEB_BASE_URLThe address of the UI. The API uses it to build links in emails, such as password reset links.stringhttp://localhost:8000CCF_WEB_BASE_URL=https://ccf.example.com
CCF_WORKER_ENABLEDStarts the background worker that runs queued jobs such as email, digests and pruning.booltrueCCF_WORKER_ENABLED=false
CCF_WORKER_USE_POLLINGMakes the worker poll the database for jobs instead of waiting on PostgreSQL LISTEN/NOTIFY.boolfalseCCF_WORKER_USE_POLLING=true
CCF_WORKFLOW_CONFIGThe path of the workflow configuration file. When the file can't be loaded, the workflow scheduler is off.stringworkflow.yamlCCF_WORKFLOW_CONFIG=/etc/ccf/workflow.yaml