COMPLYCTL(1)

πŸ“¦
version 1.1.0 Β· 3 versions
, in fedora 43, fedora 44

🌸 COMPLYCTL(1) 🌸

okay bestie, welcome to complyctl(1), the General Commands Manual page, and lemme tell you β€” this one is giving main character energy πŸ’…


✨ NAME ✨

complyctl β€” compliance assessment CLI using provider-based scanning πŸ¦‹


✨ SYNOPSIS ✨

complyctl [command] [flags]

✨ DESCRIPTION ✨

so like, complyctl is a lightweight compliance runtime πŸ’– that pulls Gemara policies straight out of an OCI registry and runs scans through providers, and then it hands you compliance reports in multiple formats: EvaluationLog, OSCAL, SARIF, and Markdown. no cap, it's literally that.

🧚 Providers 🧚

Providers are standalone executables that hook complyctl up to policy engines like OpenSCAP, Ampel, and OPA. each provider takes policy content and converts it into the engine's native input format, then translates the raw results back into the schema that complyctl uses for report generation. it's giving translator bestie 🫢

Providers talk to complyctl over gRPC and can be written in any language you want. they ship separately (like, via the complytime-providers package) and get discovered automatically by naming convention β€” complyctl-provider-* β€” from these directories:

  • ~/.local/share/complytime/providers/ (the user directory, and it takes precedence ⭐)
  • /usr/libexec/complytime/providers/ (the system directory)

Run complyctl providers to list the providers discovered on your system, and complyctl doctor to validate the whole stack, including provider health and variable requirements. 🩺

See the complytime-providers repository at https://github.com/complytime/complytime-providers for the available providers and their docs. And if you wanna write your own custom providers, see the provider authoring guide at https://github.com/complytime/complytime-providers/blob/main/docs/provider-guide.md. go off, author a provider, I believe in you πŸ’œ


πŸ‘‘ COMMANDS πŸ‘‘

πŸŽ€ init

Creates a workspace configuration file: .complytime/complytime.yaml. It interactively prompts you for policies and targets. And heads up β€” it errors if the configuration file already exists. no overwriting, bestie, it's not that kind of party πŸ™ˆ

complyctl init

πŸŽ€ get

Fetches policies and complypacks from OCI registries into the local cache. It does an incremental sync β€” meaning it only downloads new or modified content, so you're not re-downloading the same thing like a clown. Uses Docker credential helpers for authentication πŸ”

complyctl get
complyctl get --skip-verify
  • -t, --timeout duration β€” maximum time for the get operation (default: 5m).
  • --skip-verify β€” skips signature verification for fetched artifacts. ⚠️

πŸŽ€ list

Lists the cached Gemara policies along with their evaluator, control count, digest, and verification status. cute little inventory moment πŸ“

complyctl list
complyctl list --policy-id nist-800-53-r5
  • --policy-id string β€” filters the output down to a single policy.

πŸŽ€ generate

Resolves the policy dependency graph from cache, extracts assessment configurations, applies parameter overrides from complytime.yaml, and dispatches to the matching provider via the Generate RPC. it's the whole pipeline, and it ate πŸ”₯

complyctl generate --policy-id nist-800-53-r5
  • -p, --policy-id string β€” the policy ID to generate (required).
  • -t, --timeout duration β€” maximum time for the generate operation (default: 5m).

πŸŽ€ scan

Scans targets and produces compliance reports. when a target is specified and it references exactly one policy, --policy-id gets inferred for you (she's smart like that). at least one of [target] or --policy-id is required, so pick one bestie.

Output gets written to .complytime/scan/. πŸ“

complyctl scan --policy-id my-policy
complyctl scan my-target
complyctl scan my-target --policy-id my-policy --format pretty
complyctl scan --policy-id my-policy --format oscal,sarif
complyctl scan --policy-id my-policy --format all
complyctl scan --policy-id my-policy --log-format json
  • -p, --policy-id string β€” the policy ID to scan.
  • -f, --format strings β€” additional output format(s): oscal, pretty (Markdown), sarif, all (all three). accepts comma-separated values (--format oscal,sarif) or repeated flags (--format oscal --format sarif). and important: the default EvaluationLog is always produced regardless of this flag. periodt πŸ’…
  • -t, --timeout duration β€” maximum time for the scan operation (default: 5m).
  • --show-passing β€” includes passing controls in the terminal scan summary table (default: true). can also be set via COMPLYTIME_SHOW_PASSING.
  • --log-format string β€” EvaluationLog serialization format: yaml, json (default: yaml). can also be set via COMPLYTIME_LOG_FORMAT.

πŸŽ€ doctor

Runs pre-flight diagnostics on the workspace. checks provider discovery, policy cache integrity, configuration validation, complypack availability, and cache health (disk usage, orphaned versions). she's doing a full vibe check on your whole setup 🩺✨

complyctl doctor
complyctl doctor --verbose
complyctl doctor --format text
complyctl doctor --format json
  • --verbose β€” expands per-provider variable detail. πŸ”
  • -f, --format string β€” output format: human (emoji, the default), text (grep-friendly plain labels: [PASS]/[FAIL]/[WARN]), json (structured machine output). when NO_COLOR is set, text is selected automatically.

πŸŽ€ providers

Lists the discovered scanning providers with their evaluator ID, path, health status, version, and cached complypack versions. squad roll call 🫢

complyctl providers

πŸŽ€ version

Prints the version.

complyctl version

πŸŽ€ completion

Generates shell completion scripts for Bash, Zsh, Fish, or PowerShell. your tab key is about to become iconic ⭐

complyctl completion bash
complyctl completion zsh
complyctl completion fish

πŸ’– OPTIONS πŸ’–

these options apply to all commands. universal besties.

  • -d, --debug β€” outputs debug logs to stderr and the workspace log file.
  • -w, --workspace directory β€” the workspace directory. defaults to the current directory. can also be set via COMPLYTIME_WORKSPACE.
  • -h, --help β€” shows help for complyctl or any subcommand.

Run complyctl [command] --help for more information about a specific command. πŸ’œ

ngl bestie, --help is your friend. always check it before you guess πŸ™ˆ

πŸŽ€ CONFIGURATION πŸŽ€

So bestie, complyctl reads its workspace configuration from .complytime/complytime.yaml, and it looks for that in the current directory β€” or in whatever directory you pointed --workspace at. You can spawn the file with complyctl init, or just, like, write it yourself. Both are valid. πŸ’–


πŸ“¦ policies

These are the OCI references to your Gemara policy bundles. You need at least one β€” no policies, no party. 🫢

policies:
  - url: ghcr.io/myorg/policies/nist-800-53-r5:v1.0.0
    id: nist          # optional; derived from URL path if omitted
  - url: ghcr.io/myorg/policies/cis-benchmark:latest

url (required)

The full OCI reference, okay? Registry, repository, and optionally a :tag or @sha256:digest β€” like registry.example.com/policies/my-policy:v1.0. Don't be shy with the tag.

id (optional)

A short alias that targets[].policies uses to point at this entry. Skip it and the last path segment of the URL gets used instead β€” so ghcr.io/org/policies/nist-r5:v1.0 lowkey just derives nist-r5 for you. Autopilot behavior, iconic. ✨

verification (optional)

A per-entry verification override. Same fields as the workspace-level verification block (scroll down, it's there). This one wins over the workspace-level config for this entry specifically.

skip_verify (optional)

Set it to true and verification gets skipped for this entry even when workspace-level verification is configured. But heads up: it's mutually exclusive with per-entry verification. Pick a lane. πŸ’…


🧺 complypacks

OCI references to provider-specific content bundles β€” Rego policies, XCCDF profiles, mapping files, all of it. These get fetched right alongside policies during complyctl get. Every complypack gets matched to a provider by its evaluator-id.

complypacks:
  - url: ghcr.io/myorg/complypacks/ampel-bp:v1.0.0
    id: ampel-bp-pack

The fields are the same as policies β€” url, id, verification, skip_verify. And run complyctl providers to see which providers actually have complypacks, plus their evaluator IDs. πŸ‘‘


🎯 targets

The systems you're evaluating. Each target picks one or more policies by their effective ID and hands over provider-specific variables.

targets:
  - id: my-repo
    policies:
      - nist
    variables:
      url: https://github.com/myorg/myrepo
      access_token: ${GITHUB_TOKEN}

id (required)

The scan target identifier. Has to be unique across all targets β€” no dupes, bestie.

policies (required)

A list of effective policy IDs to evaluate against this target. Every one of them has to match either a policies[].id or the auto-derived ID from policies[].url. No matchy, no scanny.

variables (optional)

Provider-specific key-value pairs that get passed to the provider during scan. Supports ${VAR} environment variable substitution. And bestie, an unset variable causes a configuration error β€” so set them, fr fr. 😭

Run complyctl doctor --verbose to see the required and optional variables for each target, including one-of groups where you have to provide at least one variable in the group (like url or input_path).


🌸 variables

Workspace-scoped constants passed to all providers. Key difference from target variables: workspace variables do not support ${VAR} substitution β€” they're passed as-is. So if your value depends on the environment, put it in targets[].variables instead, okay?

variables:
  output_dir: /tmp/scan-results

πŸ” verification

OCI artifact signature verification. There are two mutually exclusive modes: keyless (Sigstore OIDC) and keyed (cosign key-pair). Omit the whole block and verification is just skipped.

Keyless verification (GitHub Actions example):

verification:
  issuer: https://token.actions.githubusercontent.com
  identity: https://github.com/myorg/myrepo/.github/workflows/release.yml@refs/tags/*

Keyed verification (public key):

verification:
  key: /path/to/cosign.pub

issuer (keyless)

The OIDC token issuer URL β€” like https://token.actions.githubusercontent.com. It requires identity. They're a package deal. 🫢

identity (keyless)

The expected SAN identity in the signing certificate. Supports glob patterns, so something like *@refs/tags/* is fair game. ✨

key (keyed)

Path to a PEM-encoded public key. Mutually exclusive with issuer/identity β€” it's one or the other, no mixing.

trusted_root (keyless, optional)

Path to a trusted_root.json file for keyless verification against private Sigstore instances. Mutually exclusive with key, and it requires issuer and identity. Private-instance girlies, this one's for you. πŸ’œ

Per-entry verification can be set on individual policies[] or complypacks[] entries, and it overrides the workspace-level config:

policies:
  - url: ghcr.io/myorg/policies/internal-policy:v1.0
    verification:
      key: /path/to/internal.pub
  - url: ghcr.io/thirdparty/policy:v2.0
    skip_verify: true

🌈 Complete example

Everything together, one gorgeous little file:

policies:
  - url: quay.io/complytime/policies-ampel-branch-protection:latest
    id: ampel-bp
complypacks:
  - url: ghcr.io/myorg/complypacks/ampel-bp:v1.0.0
    id: ampel-bp-pack
variables:
  output_dir: /tmp/results
verification:
  issuer: https://token.actions.githubusercontent.com
  identity: https://github.com/complytime/complyctl/.github/workflows/release.yml@refs/tags/*
targets:
  - id: my-repo
    policies:
      - ampel-bp
    variables:
      url: https://github.com/myorg/myrepo
      access_token: ${GITHUB_TOKEN}

🌿 ENVIRONMENT 🌿

Environment variables, bestie. They're how you tweak complyctl without retyping flags forever.

  • COMPLYTIME_WORKSPACE β€” Overrides the workspace directory that complyctl uses. When it's set, complyctl resolves config and output paths relative to that directory. But plot twist: the --workspace flag takes precedence. πŸ’…
  • COMPLYTIME_SHOW_PASSING β€” Set it to false and passing controls get excluded from the terminal scan summary table. Default: true (show all controls). And yep, the --show-passing flag takes precedence.
  • COMPLYTIME_LOG_FORMAT β€” The EvaluationLog serialization format: yaml or json. Default: yaml. The --log-format flag takes precedence.
  • COMPLYTIME_CACHE_VERSIONS β€” How many complypack versions to retain per evaluator-id in the local cache (~/.cache/complytime/complypacks/). Default: 1. Values less than 1 get clamped to 1 β€” no zero, no negatives, we don't do that here.
  • COMPLYTIME_SYSTEM_PROVIDER_DIR β€” Overrides the system-wide provider directory that gets scanned after the user provider directory. Providers in the user directory take precedence. Must be an absolute path β€” a relative path is just ignored. Default: /usr/libexec/complytime/providers.
  • NO_COLOR β€” When set (any non-empty value), complyctl doctor automatically picks text format instead of the default human-readable emoji output. Follows the NO_COLOR convention at https://no-color.org. And ngl, it has no effect when --format is specified explicitly.

πŸ’€ EXIT CODES πŸ’€

  • 0 β€” Command completed successfully. Scan findings (passed, failed, not applicable) get reported in the output, but bestie, they do not affect the exit code. Policy findings are data, not errors. Periodt. ✨
  • 1 β€” An operational error happened. This covers provider failures, invalid configuration, or zero requirements assessed. Reports and summaries get written before the non-zero exit, so partial results stay available. 🫢
Okay so this part matters: to gate a pipeline on compliance results, parse the scan output (SARIF, OSCAL) with your policy engine rather than relying on the exit code. The exit code is not your gate, bestie. Don't do it.

πŸ“ FILES πŸ“

  • ~/.cache/complytime/policies/ β€” OCI Layout cache for fetched policies (one store per policy ID). Follows the XDG Base Directory Specification ($XDG_CACHE_HOME).
  • ~/.cache/complytime/complypacks/ β€” Complypack cache with version retention per evaluator-id.
  • ~/.local/share/complytime/state.json β€” Digest tracking for incremental policy sync. Follows the XDG Base Directory Specification ($XDG_DATA_HOME).
  • ~/.local/share/complytime/providers/ β€” User-installed provider executables (takes precedence over the system directory).
  • /usr/libexec/complytime/providers/ β€” System-installed provider executables.
  • .complytime/complytime.yaml β€” The workspace configuration file. See the CONFIGURATION section for the full schema reference.
  • .complytime/scan/ β€” Scan output reports (EvaluationLog, OSCAL, SARIF, Markdown).
  • .complytime/complyctl.log β€” Debug log file (created when --debug is used).

πŸ¦‹ SEE ALSO πŸ¦‹


Β© 2025-2026 Red Hat, Inc. Complyctl is released under the terms of the Apache-2.0 license.


πŸ’– AUTHORS πŸ’–

Marcus Burghardt maburgha@redhat.com


And that's the whole page, bestie!! πŸŽ€ This was the Complyctl Manual, dated September 2026 β€” the COMPLYCTL(1) page, complete and slaying. Go forth and comply, iykyk. πŸ’…βœ¨

πŸ“¦ where this page comes from