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.
| Setting | Purpose | Type | Default | Example |
|---|---|---|---|---|
agent_evidence.emit_on_run_completion | Sends that evidence as soon as a run completes, and when downloading plugins or policies fails at startup. | bool | true | false |
agent_evidence.enabled | Makes 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. | bool | true | false |
agent_evidence.interval | How often a daemon sends that evidence, whatever the plugins are doing. 0s turns the periodic evidence off. The evidence expires after five intervals. | duration | 1h | 30m |
api.auth.client_id | The 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. | string | none | 123e4567-e89b-12d3-a456-426614174000 |
api.auth.client_secret | The client secret of that key. Treat it as a secret, and prefer CCF_API_AUTH_CLIENT_SECRET to the file. | string | none | <the key's client secret> |
api.url | The address of the API the agent sends evidence and heartbeats to. | string | required | https://ccf-api.example.com |
daemon | Runs 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. | bool | false | true |
plugins.<name>.config | The 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. | map | none | {token: "${env:GITHUB_TOKEN}"} |
plugins.<name>.enabled | Turns a plugin off without removing it. A disabled plugin isn't downloaded or run, but the agent still reports it. (new in 0.9) | bool | true | false |
plugins.<name>.labels | Labels 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. | map | none | {environment: production} |
plugins.<name>.policies | The 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. | list | none | ["ghcr.io/compliance-framework/plugin-apt-versions-policies:v0.5.1"] |
plugins.<name>.policy_behavior | Maps 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. | map | none | {privileged: [cluster-admin]} |
plugins.<name>.policy_data | Data the policies can read as data while they evaluate, such as allowed values. It can have any shape. | object | none | {allowed_ports: [22, 443]} |
plugins.<name>.protocol_version | The plugin protocol the plugin speaks, 1 or 2. A version 2 plugin gets an Init call before each Eval. See Plugins. | int | the org.ccf.plugin.protocol.version annotation of an OCI source, otherwise 1 | 2 |
plugins.<name>.schedule | When 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>.source | Where 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. | string | required | ghcr.io/compliance-framework/plugin-apt-versions:v0.7.0 |
remote_config.allow_local_sources | Lets an overlay add a plugin or policy from a local path. Even then, it only applies in apply_all mode. (new in 0.9) | bool | false | true |
remote_config.mode | What 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) | string | report with api.auth, otherwise off | apply_safe |
remote_config.overridable_config_flags | The 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_interval | How often the agent asks the API for a new overlay. At least 15s. (new in 0.9) | duration | 60s | 5m |
remote_config.trusted_sources | Glob 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/*"] |
verbosity | How 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). | int | 0 | 1 |
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_.
| Setting | Purpose | Type | Default | Example |
|---|---|---|---|---|
CCF_API_AUTH_CLIENT_ID | Sets api.auth.client_id, even when the file doesn't. The submit-evidence command reads it too. | string | none | CCF_API_AUTH_CLIENT_ID=123e4567-e89b-12d3-a456-426614174000 |
CCF_API_AUTH_CLIENT_SECRET | Sets api.auth.client_secret, even when the file doesn't. The submit-evidence command reads it too. Plugins never see it. | string | none | CCF_API_AUTH_CLIENT_SECRET=<the key's client secret> |
CCF_API_URL | The API address for the submit-evidence command, when it has no --api-url. The agent command reads api.url from its file instead. | string | none | CCF_API_URL=https://ccf-api.example.com |
CCF_INSTANCE_ID | Pins 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) | string | the ID stored in the state directory, created on the first run | CCF_INSTANCE_ID=0b6f8c2e-4d1a-4f5e-9a3b-7c2d1e0f9a8b |
CCF_REMOTE_CONFIG_MODE | Sets remote_config.mode, even when the file has no remote_config block. (new in 0.9) | string | none | CCF_REMOTE_CONFIG_MODE=apply_safe |
CCF_STATE_DIR | The 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 path | CCF_STATE_DIR=/var/lib/ccf-agent/state |
INPUT_API_URL | The API address for the submit-evidence command when neither --api-url nor CCF_API_URL is set. | string | none | INPUT_API_URL=https://ccf-api.example.com |
KUBERNETES_POD | Used as the agent's _agent label when api.auth.client_id and KUBERNETES_POD_NAME are unset. | string | none | KUBERNETES_POD=ccf-agent-7d9f8 |
KUBERNETES_POD_NAME | Used 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. | string | none | KUBERNETES_POD_NAME=ccf-agent-7d9f8 |
Flags of the agent command
A flag wins over the configuration file.
| Setting | Purpose | Type | Default | Example |
|---|---|---|---|---|
-c, --config | The configuration file. | string | required | --config /etc/ccf-agent/config.yaml |
-d, --daemon | Runs the agent as a daemon, like daemon in the file. | bool | false | -d |
--instance-id | Pins the instance's ID, like CCF_INSTANCE_ID, and wins over it. (new in 0.9) | string | see CCF_INSTANCE_ID | --instance-id 0b6f8c2e-4d1a-4f5e-9a3b-7c2d1e0f9a8b |
--state-dir | The state directory, like CCF_STATE_DIR, and wins over it. (new in 0.9) | string | see CCF_STATE_DIR | --state-dir /var/lib/ccf-agent/state |
-v, --verbose | Raises verbosity by one each time you repeat it. A remote overlay's verbosity wins over it. | int | 0 | -vv |