A lightweight compliance runtime that pulls Gemara policies from an OCI registry and executes scans via providers.

Architecture#

┌──────────────────────────────────────────────────────────────────┐
│  Host                                                            │
│                                                                  │
│  ┌──────────────┐      complyctl get   ┌───────────────────────┐ │
│  │ OCI Registry │ ◄──────────────────  │                       │ │
│  │              │  ───────────────────►│    complyctl CLI      │ │
│  │  Gemara      │   catalog + policy   │                       │ │
│  │  policies    │   layers (YAML)      │ init / get / list     │ │
│  └──────────────┘                      │ generate / scan       │ │
│                                        │ doctor / providers    │ │
│                                        │ version               │ │
│                                        └─────┬────────┬────────┘ │
│                                              │        │          │
│                                 ┌────────────┘        │          │
│                                 │                     │          │
│                                 ▼                     ▼          │
│                       ┌──────────────┐    ┌────────────────┐     │
│                       │    Cache     │    │     Data       │     │
│                       │              │    │                │     │
│                       │ ~/.cache/    │    │ ~/.local/share │     │
│                       │  complytime/ │    │  /complytime/  │     │
│                       │  policies/   │    │  providers/    │     │
│                       │              │    │  state.json    │     │
│                       │ OCI Layout   │    │                │     │
│                       │ per policy   │    │ complyctl-     │     │
│                       └──────────────┘    │  provider-*    │     │
│                                           │                │     │
│                                           │ gRPC: Describe │     │
│                                           │ Generate, Scan │     │
│  ┌──────────────┐                         └────────────────┘     │
│  │  Workspace   │                                                │
│  │              │  .complytime/complytime.yaml defines:           │
│  │ .complytime/ │   - registry URL                               │
│  │  complytime  │   - policy IDs + versions                      │
│  │   .yaml      │   - targets + variables                        │
│  │  scan/       │                                                │
│  │  (output)    │  Scan output (EvaluationLog, OSCAL,            │
│  └──────────────┘   SARIF, Markdown) written to workspace        │
└──────────────────────────────────────────────────────────────────┘

Components:

ComponentDescription
OCI RegistryRemote store for Gemara policies. Supports two OCI manifest layouts: split-layer (distinct media types per artifact) and Gemara bundle format (single artifact media type with annotation-based differentiation). Both formats are auto-detected and resolved transparently.
WorkspaceResolved workspace directory containing .complytime/complytime.yaml (or legacy complytime.yaml at root). Configurable via --workspace flag or COMPLYTIME_WORKSPACE env var. Defines which registry, policies, and targets to use. Scan output lands in .complytime/scan/.
CacheLocal OCI Layout stores under ~/.cache/complytime/policies/. One store per policy ID. Follows the XDG Base Directory Specification ($XDG_CACHE_HOME).
DataPersistent data under ~/.local/share/complytime/ ($XDG_DATA_HOME). Includes state.json (digest tracking for incremental sync) and providers/ (provider binaries).
ProvidersStandalone executables in ~/.local/share/complytime/providers/ matching the complyctl-provider-* naming convention. Communicate via gRPC (Describe, Generate, Scan). Evaluator ID derived from filename.
CLIOrchestrates the workflow: fetch policies, resolve dependency graphs, dispatch to providers, produce compliance reports.

Documentation#

CLI Commands#

CommandDescription
initCreate a workspace configuration file
getFetch new/modified policies from OCI registry and update cache
listList cached Gemara policies
generateGenerate policy graph and invoke providers
scanScan targets and produce compliance reports
doctorRun pre-flight diagnostics on the workspace
providersList discovered scanning providers and their health status
versionPrint version

Global flags:

  • --debug / -d — output debug logs
  • --workspace / -w — workspace directory (project root containing .complytime/, defaults to current directory)

Run Commands From Any Directory#

Use the --workspace flag to run commands from any directory:

## Run From A Different Directory
complyctl scan --workspace ~/projects/myapp

## Using Relative Path
complyctl scan --workspace ../myapp

## Using Environment Variable
export COMPLYTIME_WORKSPACE=~/projects/myapp
complyctl scan

Config File Location#

complyctl organizes all workspace-specific files under .complytime/ to keep your repository root clean and avoid configuration conflicts.

  • .complytime/complytime.yaml - Configuration file (policies, targets, variables)
  • .complytime/scan/ - Scan output reports
  • .complytime/complyctl.log - Debug log file
  • .complytime/generation/ - Generation state (per-policy freshness tracking)

Note: For backward compatibility, complyctl still supports complytime.yaml at the repository root, but this location is deprecated. Move your config to .complytime/complytime.yaml:

mkdir -p .complytime
mv complytime.yaml .complytime/complytime.yaml

init#

complyctl init

Creates a workspace configuration file (.complytime/complytime.yaml). Errors if one already exists.

get#

complyctl get

Performs incremental sync from the OCI registry defined in complytime.yaml. Only downloads new or modified content. Uses Docker credential helpers for authentication — if docker login works, complyctl get works.

list#

complyctl list
complyctl list --policy-id nist-800-53-r5
FlagDescription
--policy-idFilter output to a single policy

generate#

complyctl generate --policy-id nist-800-53-r5
FlagShortDescription
--policy-id-pPolicy ID to generate (required)

Resolves the policy dependency graph from cache, extracts assessment configurations, applies parameter overrides from complytime.yaml, and dispatches to the matching provider via Generate RPC.

scan#

## Scan A Specific Target (policy Inferred If Target Has Exactly One)
complyctl scan prod

## Scan A Specific Target For A Specific Policy
complyctl scan prod --policy-id nist-800-53-r5

## Scan All Targets For A Policy
complyctl scan --policy-id nist-800-53-r5

## With Output Format
complyctl scan prod --format oscal
complyctl scan --policy-id nist-800-53-r5 --format pretty
complyctl scan --policy-id nist-800-53-r5 --format sarif
Argument / FlagShortDescription
[target]Optional target ID to scope the scan (from complytime.yaml)
--policy-id-pPolicy ID to scan (required when no target is given, or target has multiple policies)
--format-fOutput format: oscal, pretty, sarif

When a target is specified and references exactly one policy, --policy-id is inferred. At least one of [target] or --policy-id is required.

Output written to ./.complytime/scan/.

Exit Codes#
Exit CodeMeaning
0Scan completed – all targets evaluated (findings, if any, are in the report)
non-zeroOperational error – one or more targets could not be evaluated, or zero requirements assessed (partial results written before exit)

Policy violations (failed requirements) do not cause a non-zero exit. Operational errors (missing tools, clone failures, auth errors, zero requirements assessed) do.

doctor#

complyctl doctor
complyctl doctor --verbose

Validates workspace configuration, provider health, cache integrity, and provider variable requirements. Use --verbose for per-provider variable detail.

providers#

complyctl providers

Lists discovered scanning providers with their evaluator ID, path, health status, and version.

Workspace Configuration#

## .complytime/complytime.yaml
policies:
  - url: registry.example.com/policies/nist-800-53-r5:v1.0.0
    id: nist
  - url: registry.example.com/policies/cis-benchmark
variables:
  output_dir: /tmp/scan-results
targets:
  - id: production-cluster
    policies:
      - nist
    variables:
      kubeconfig: /path/to/kubeconfig
      api_token: ${MY_API_TOKEN}
FieldDescription
policies[].urlFull OCI reference (registry + repository + optional :tag)
policies[].idOptional shortname; if omitted, derived from last path segment of URL
variablesWorkspace-scoped constants passed to providers via Generate RPC
targets[].idScan target identifier
targets[].policiesList of effective policy IDs to evaluate against this target
targets[].variablesProvider-specific key-value pairs; supports ${VAR} env substitution

Contributing#

Interested in writing a provider? See the Provider Guide.