Skip to main content

Configuration reference

This page is for operators. The Continuous Compliance Framework (CCF) Agent reads a configuration file, a few environment variables and the flags of its agent command.

Configuration file​

Pass the file with --config. It can be YAML, JSON or TOML: the agent goes by the file's extension. Keys are lowercase, and <name> stands for a plugin name you choose.

An environment variable named CCF_ followed by a key's path in upper case, with _ between the parts, overrides that key when the file sets it: CCF_PLUGINS_GITHUB_CONFIG_TOKEN overrides plugins.github.config.token. Only api.auth.client_id, api.auth.client_secret and remote_config.mode can come from the environment when the file doesn't set them.

SettingPurposeTypeDefaultExample
agent_evidence.emit_on_run_completionSends that evidence as soon as a run completes, and when downloading plugins or policies fails at startup.booltruefalse
agent_evidence.enabledMakes the agent send evidence about its own runs (labels _agent, tool=ccf and type=operations). It's not-satisfied while any plugin's last run failed.booltruefalse
agent_evidence.intervalHow often a daemon sends that evidence, whatever the plugins are doing. 0s turns the periodic evidence off. The evidence expires after five intervals.duration1h30m
api.auth.client_idThe client ID of a service account key of the agent, which the agent signs in to the API with. It must be a UUID. Set it with api.auth.client_secret, or leave both unset. You can also set it with CCF_API_AUTH_CLIENT_ID.stringnone123e4567-e89b-12d3-a456-426614174000
api.auth.client_secretThe client secret of that key. Treat it as a secret, and prefer CCF_API_AUTH_CLIENT_SECRET to the file.stringnone<the key's client secret>
api.urlThe address of the API the agent sends evidence and heartbeats to.stringrequiredhttps://ccf-api.example.com
daemonRuns the agent as a long-running process that runs each plugin on its schedule, sends heartbeats and reloads the file when it changes. Off, the agent runs every plugin once and exits.boolfalsetrue
plugins.<name>.configThe plugin's own settings, passed to it as strings. A value can use ${env:NAME} to read the environment variable NAME when the agent loads its configuration, either as the whole value or inside a longer one.mapnone{token: "${env:GITHUB_TOKEN}"}
plugins.<name>.enabledTurns a plugin off without removing it. A disabled plugin isn't downloaded or run, but the agent still reports it. (new in 0.9)booltruefalse
plugins.<name>.labelsLabels added to every evidence record the plugin sends, besides the _agent and _plugin labels the agent sets. Evidence UUIDs come from labels, so changing them starts a new evidence stream.mapnone{environment: production}
plugins.<name>.policiesThe policy bundles the plugin evaluates its data against. Each is a local path or an OCI image tag, which the agent downloads into .compliance-framework/policies.listnone["ghcr.io/compliance-framework/plugin-apt-versions-policies:v0.5.1"]
plugins.<name>.policy_behaviorMaps a part of a policy path to a list of behaviors, for plugins that treat some policies differently. The agent passes it to the plugin unchanged.mapnone{privileged: [cluster-admin]}
plugins.<name>.policy_dataData the policies can read as data while they evaluate, such as allowed values. It can have any shape.objectnone{allowed_ports: [22, 443]}
plugins.<name>.protocol_versionThe plugin protocol the plugin speaks, 1 or 2. A version 2 plugin gets an Init call before each Eval. See Plugins.intthe org.ccf.plugin.protocol.version annotation of an OCI source, otherwise 12
plugins.<name>.scheduleWhen the plugin runs in daemon mode, as a five-field cron expression (minute, hour, day of month, month, day of week) or a descriptor such as @hourly. If it doesn't parse, the agent logs it and skips that plugin.string* * * * * (every minute)"0 * * * *"
plugins.<name>.sourceWhere the plugin comes from. Either a local path, to the plugin executable or to a directory with a plugin executable in it, or an OCI image tag, which the agent downloads for its own OS and architecture into .compliance-framework/plugins.stringrequiredghcr.io/compliance-framework/plugin-apt-versions:v0.7.0
remote_config.allow_local_sourcesLets an overlay add a plugin or policy from a local path. Even then, it only applies in apply_all mode. (new in 0.9)boolfalsetrue
remote_config.modeWhat the agent does with the configuration overlay an administrator saves in the API. off doesn't report or fetch anything; report reports the agent's configuration but never applies an overlay; apply_safe applies an overlay when every change in it is safe; apply_all also applies unsafe changes. Without api.auth the mode is always off. Set it locally only (file, environment or flag); an overlay can't change it. (new in 0.9)stringreport with api.auth, otherwise offapply_safe
remote_config.overridable_config_flagsThe plugin config keys an overlay may change as a safe change. An entry is a key glob for every plugin (token), a plugin and key glob (github:token), or *. (new in 0.9)list[]["github:org", "schedule_*"]
remote_config.poll_intervalHow often the agent asks the API for a new overlay. At least 15s. (new in 0.9)duration60s5m
remote_config.trusted_sourcesGlob patterns of plugin and policy sources an overlay may add as a safe change, such as ghcr.io/compliance-framework/*. * doesn't match /. (new in 0.9)list[]["ghcr.io/compliance-framework/*"]
verbosityHow much the agent logs. 0 logs errors, warnings and info, 1 adds debug and 2 adds trace. A negative value logs less (-1 logs warnings and errors).int01

Environment variables​

The variables the agent reads besides the CCF_ overrides of file keys. Plugins get the agent's environment, except the variables whose names start with CCF_API_AUTH_.

SettingPurposeTypeDefaultExample
CCF_API_AUTH_CLIENT_IDSets api.auth.client_id, even when the file doesn't. The submit-evidence command reads it too.stringnoneCCF_API_AUTH_CLIENT_ID=123e4567-e89b-12d3-a456-426614174000
CCF_API_AUTH_CLIENT_SECRETSets api.auth.client_secret, even when the file doesn't. The submit-evidence command reads it too. Plugins never see it.stringnoneCCF_API_AUTH_CLIENT_SECRET=<the key's client secret>
CCF_API_URLThe API address for the submit-evidence command, when it has no --api-url. The agent command reads api.url from its file instead.stringnoneCCF_API_URL=https://ccf-api.example.com
CCF_INSTANCE_IDPins the agent instance's ID, so repeated one-shot runs (CI jobs, Kubernetes jobs) report as one instance. It must be a UUID. The agent doesn't store it. --instance-id wins over it. (new in 0.9)stringthe ID stored in the state directory, created on the first runCCF_INSTANCE_ID=0b6f8c2e-4d1a-4f5e-9a3b-7c2d1e0f9a8b
CCF_REMOTE_CONFIG_MODESets remote_config.mode, even when the file has no remote_config block. (new in 0.9)stringnoneCCF_REMOTE_CONFIG_MODE=apply_safe
CCF_STATE_DIRThe directory where the agent keeps its instance ID and its cache of the remote configuration. Pin it to a persistent volume in a container. --state-dir wins over it. (new in 0.9)string.compliance-framework/state/<key> in the working directory, where the key comes from the config file's absolute pathCCF_STATE_DIR=/var/lib/ccf-agent/state
INPUT_API_URLThe API address for the submit-evidence command when neither --api-url nor CCF_API_URL is set.stringnoneINPUT_API_URL=https://ccf-api.example.com
KUBERNETES_PODUsed as the agent's _agent label when api.auth.client_id and KUBERNETES_POD_NAME are unset.stringnoneKUBERNETES_POD=ccf-agent-7d9f8
KUBERNETES_POD_NAMEUsed as the agent's _agent label when api.auth.client_id is unset. Without either, the label is a hash of the plugin and agent evidence configuration.stringnoneKUBERNETES_POD_NAME=ccf-agent-7d9f8

Flags of the agent command​

A flag wins over the configuration file.

SettingPurposeTypeDefaultExample
-c, --configThe configuration file.stringrequired--config /etc/ccf-agent/config.yaml
-d, --daemonRuns the agent as a daemon, like daemon in the file.boolfalse-d
--instance-idPins the instance's ID, like CCF_INSTANCE_ID, and wins over it. (new in 0.9)stringsee CCF_INSTANCE_ID--instance-id 0b6f8c2e-4d1a-4f5e-9a3b-7c2d1e0f9a8b
--state-dirThe state directory, like CCF_STATE_DIR, and wins over it. (new in 0.9)stringsee CCF_STATE_DIR--state-dir /var/lib/ccf-agent/state
-v, --verboseRaises verbosity by one each time you repeat it. A remote overlay's verbosity wins over it.int0-vv