Operations

Monitoring

Audit logs, log formats, and alerting recommendations.

Monitoring

OpenApe produces audit logs at three levels: IdP, proxy, and escapes. All use JSONL format (one JSON object per line) for easy parsing.

Audit Log Sources

SourceLocationWhat it logs
IdPApplication logs (stdout/stderr)Logins, registrations, grant decisions, agent enrollment
ProxyConfigurable (audit_log in TOML)Every HTTP request, rule evaluation, grant requests
escapes/var/log/openape/audit.logEvery command execution, verification results

escapes Audit Log

Every execution attempt is logged:

{"timestamp":"2025-01-15T10:30:00Z","grant_id":"abc123","command":["systemctl","restart","nginx"],"requester":"agent+deploy@example.com","approver":"admin@example.com","result":"success","exit_code":0,"duration_ms":1234}

Failed attempts include error details:

{"timestamp":"2025-01-15T10:31:00Z","error":"cmd_hash mismatch","command":["rm","-rf","/"],"requester":"agent+deploy@example.com","result":"verification_failed"}

Fields

FieldTypeDescription
timestampstringISO 8601
grant_idstringGrant UUID
commandstring[]Command that was (or would have been) executed
requesterstringAgent email
approverstringWho approved the grant
resultstringsuccess, verification_failed, exec_failed
exit_codenumberCommand exit code
duration_msnumberExecution time
errorstringError message (on failure)

Proxy Audit Log

Every request through the proxy is logged:

{"ts":"2025-01-15T10:30:00.123Z","agent":"agent+deploy@example.com","action":"allow","domain":"api.github.com","method":"GET","path":"/repos/org/repo","grant_id":null,"rule":"allow[0]","waited_ms":0}

Fields

FieldTypeDescription
tsstringISO 8601 with milliseconds
agentstringAgent email
actionstringallow, deny, grant_approved, grant_denied, grant_timeout, error
domainstringTarget domain
methodstringHTTP method
pathstringRequest path
grant_idstring | nullAssociated grant ID (if grant_required rule matched)
rulestringWhich rule matched (e.g., allow[0], deny[2])
waited_msnumberTime spent waiting for grant approval
request_hashstringRequest fingerprint for deduplication
errorstringError message (if action is error)

Querying Logs

Find all denied grants

grep '"action":"deny"' /var/log/openape-proxy/audit.jsonl | jq .

Find failed escapes executions

grep '"result":"verification_failed"' /var/log/openape/audit.log | jq .

Count requests per agent

cat /var/log/openape-proxy/audit.jsonl | jq -r '.agent' | sort | uniq -c | sort -rn

Find all actions by a specific agent

grep 'agent+deploy@example.com' /var/log/openape-proxy/audit.jsonl | jq -c '{ts, action, domain, method}'

Alerting Recommendations

Critical Alerts

ConditionWhat it meansQuery
Multiple verification_failed from same agentPossible key compromise or misconfigurationresult == "verification_failed" count > 5 in 1h
cmd_hash mismatchSomeone is trying to run a different command than approvederror contains "cmd_hash"
Unknown agent email in logsUnauthorized agent attempting accessagent not in known_agents
Management Token used from unexpected IPPossible token leakIdP access logs

Warning Alerts

ConditionWhat it means
High volume of grant_timeoutApprovers not responding to grant requests
deny rate > 50%Rules may be too restrictive, or agents misconfigured
once grants created but never consumedAgents requesting but not using grants

Log Rotation

escapes

# logrotate config: /etc/logrotate.d/openape
/var/log/openape/audit.log {
    daily
    rotate 90
    compress
    delaycompress
    missingok
    notifempty
}

Proxy

Configure rotation for the proxy audit log similarly, or pipe to a log aggregation service (Datadog, Loki, etc.).

Integration with Log Aggregation

JSONL format is directly compatible with:

  • Datadog — use the file tailing agent
  • Grafana Loki — use promtail with JSON parsing
  • ELK Stack — use Filebeat with JSON input
  • CloudWatch — pipe to CloudWatch Logs agent

Each JSONL entry is a self-contained JSON object, so no multi-line parsing is needed.