CLI Integration
How clef report communicates with Clef Pro.
Authentication
All CLI endpoints use API key authentication:
x-api-key: clef_<token>The API key resolves to a specific team and integration. No JWT or OAuth required.
Flow
1. Fetch config and last known state
GET /api/v1/integrations/:integrationIdThe CLI reads two fields from the response:
lastCommitSha— the commit hash of the most recent report (nullif first run)config— collection settings (e.g. whether to include CI context)
2. Determine what to report
bash
if lastCommitSha is null:
# First report — evaluate HEAD only
commits = [HEAD]
elif lastCommitSha == HEAD:
# Up to date — nothing to do
exit 0
else:
# Backfill — all commits since last report
commits = $(git log <lastCommitSha>..HEAD --reverse)3. Evaluate locally
For each commit, the CLI:
- Checks out the commit
- Evaluates each namespace/environment for health status
- Computes drift across environments per namespace
- Evaluates policy rules (configured on the integration)
- Composes human-readable descriptions — no raw metadata leaves the CI
4. Submit
Single commit:
POST /api/v1/reportsMultiple commits (backfill):
POST /api/v1/reports/batchReport schema
Single report body
json
{
"commitSha": "a1b2c3d4e5f6...",
"commitTimestamp": 1700000000000,
"branch": "main",
"cliVersion": "1.0.0",
"summary": {
"filesScanned": 12,
"namespaces": ["database", "oauth"],
"environments": ["production", "staging"],
"cells": [
{
"namespace": "database",
"environment": "production",
"healthStatus": "healthy",
"description": "4 keys, 3 recipients, rotated 12d ago"
}
],
"violations": 1,
"passed": false
},
"drift": [
{
"namespace": "database",
"isDrifted": true,
"severity": "warning",
"summary": "Development has an additional recipient"
}
],
"policyResults": [
{
"ruleId": "missing_keys",
"ruleName": "Missing encryption keys",
"passed": false,
"severity": "critical",
"message": "Missing key detected in oauth/production",
"scope": "oauth/production"
}
],
"ci": {
"provider": "github_actions",
"pipelineUrl": "https://github.com/acme/platform/actions/runs/123",
"triggeredBy": "push"
}
}Batch report body
json
{
"cliVersion": "1.0.0",
"reports": [
{ "commitSha": "oldest...", "commitTimestamp": 1700000000000, "branch": "main", "summary": {}, "drift": [], "policyResults": [] },
{ "commitSha": "middle...", "commitTimestamp": 1700001000000, "branch": "main", "summary": {}, "drift": [], "policyResults": [] },
{ "commitSha": "head...", "commitTimestamp": 1700002000000, "branch": "main", "summary": {}, "drift": [], "policyResults": [], "ci": {} }
]
}- Max 500 reports per batch
- Ordered oldest → newest (last = HEAD)
- Alerts generated only from the last report
Idempotency
Reports are keyed by commit hash. Submitting the same commit twice overwrites the previous record. This is an upsert, not an insert.
- Single report retries: safe, always overwrites
- Batch retries: safe, every report in the batch overwrites its previous version
- Partial batch retries: safe, already-written reports get overwritten with identical data
The retry logic is: if you didn't get a 201, send the same request again. No dedup tokens, no delta computation.
The report tracks createdAt (first write, preserved on retry) and updatedAt (every write). If they differ, the report was retried.
Responses
Single report (201)
json
{
"data": {
"reportId": "a1b2c3d...",
"passed": false,
"violations": 1,
"alertsGenerated": 1
},
"success": true
}Batch report (201)
json
{
"data": {
"reportsWritten": 15,
"alertsGenerated": 1
},
"success": true
}Errors
| Status | Meaning | Action |
|---|---|---|
| 201 | Success | Done |
| 400 | Validation error (bad schema) | Fix payload |
| 401 | Invalid or revoked API key | Fix key |
| 500 | Server error | Retry (idempotent) |
| Timeout | Unknown state | Retry (idempotent) |