Skip to content

API Audit

Maks Zaikin edited this page Jul 1, 2026 · 1 revision

title: "API — Audit & Reporting" category: "api" version: "1.0" last_updated: "2024-01-15" standards: ["NIST-SP-800-53", "FSTEC"] related_pages: ["API-Overview", "Security-Audit-Model", "Database-Identity-DB", "Database-Assets-DB", "Database-Secrets-DB"] ai_summary: "VaultFlower Audit and Reporting API endpoints. GET /audit/events (search all three audit logs), GET /audit/events/{id} (event details with CEF), GET /audit/events/export (CSV/JSON export). Reports: checkout-summary, rotation-summary, security-alerts, compliance, user-activity. Health check endpoints (no auth) for Consul monitoring."

📊 API — Audit & Reporting

Base Path

https://vfw-core.contoso.com/api/v1/{tenant-slug}/audit/

Access: Auditor and Admin roles only (except health endpoints).


Audit Log

GET /audit/events

Search across all three audit logs simultaneously.

GET /api/v1/acme-corp/audit/events?source=all&severity=CRITICAL&from_date=2024-01-15T00:00:00Z&to_date=2024-01-15T23:59:59Z
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Query parameters:

Parameter Type Required Description
source string No identity / assets / secrets / all (default: all)
event_type string No Filter by event type (e.g. checkout.scope_violation)
severity string No INFO / WARN / ERROR / CRITICAL
actor_upn string No Filter by actor UPN
target_type string No Filter by target type
target_id UUID No Filter by specific target object
result string No success / failure / blocked
ip_address string No Filter by source IP
x_request_id UUID No Find all events for a specific request
from_date datetime Yes Start of search window (ISO 8601)
to_date datetime Yes End of search window (ISO 8601)
page integer No Default: 1
page_size integer No Default: 50, max: 200

Response 200:

{
  "items": [
    {
      "id": "d0e1f2a3-b4c5-6789-defa-789012345678",
      "source": "secrets",
      "event_time": "2024-01-15T22:30:15.123Z",
      "event_type": "checkout.scope_violation",
      "severity": "CRITICAL",
      "actor_upn": "unknown@company.com",
      "target_type": "credential",
      "target_id": "e5f6a7b8-...",
      "ip_address": "192.168.10.99",
      "result": "blocked",
      "details": {
        "attempted_asset": "SRV-OT-001",
        "asset_zone": "Safety-Zone",
        "user_scopes": ["OT-DMZ-North"]
      },
      "x_request_id": "a1b2c3d4-..."
    },
    {
      "id": "e1f2a3b4-c5d6-7890-efab-890123456789",
      "source": "identity",
      "event_time": "2024-01-15T08:06:00.000Z",
      "event_type": "mfa.password_verified",
      "severity": "INFO",
      "actor_upn": "operator@company.com",
      "target_type": "user",
      "target_id": "f1e2d3c4-...",
      "ip_address": "192.168.10.50",
      "result": "success",
      "details": {
        "factor_number": 1,
        "checkout_request_id": "b8c9d0e1-..."
      },
      "x_request_id": "b2c3d4e5-..."
    }
  ],
  "total": 1547,
  "page": 1,
  "page_size": 50,
  "total_pages": 31,
  "from_date": "2024-01-15T00:00:00Z",
  "to_date": "2024-01-15T23:59:59Z"
}

Response 400 — Missing date range:

{
  "error": {
    "code": "DATE_RANGE_REQUIRED",
    "message": "Both from_date and to_date are required for audit queries"
  }
}

Tip — Cross-DB correlation:

Use x_request_id to find all events related to a single operation:
GET /audit/events?x_request_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890&from_date=...&to_date=...

Returns all events across identity, assets, and secrets
that share the same X-Request-ID header.

GET /audit/events/{event-id}

Get full event details including CEF string.

GET /api/v1/acme-corp/audit/events/d0e1f2a3-b4c5-6789-defa-789012345678?source=secrets
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Query parameters:

Parameter Type Required Description
source string Yes identity / assets / secrets — which DB to look in

Response 200:

{
  "id": "d0e1f2a3-b4c5-6789-defa-789012345678",
  "source": "secrets",
  "event_time": "2024-01-15T22:30:15.123Z",
  "event_type": "checkout.scope_violation",
  "severity": "CRITICAL",
  "actor_id": "f1e2d3c4-...",
  "actor_upn": "unknown@company.com",
  "target_type": "credential",
  "target_id": "e5f6a7b8-...",
  "ip_address": "192.168.10.99",
  "result": "blocked",
  "details": {
    "attempted_asset": "SRV-OT-001",
    "asset_zone": "Safety-Zone",
    "user_scopes": ["OT-DMZ-North"],
    "violation_type": "zone_out_of_scope"
  },
  "cef_raw": "CEF:0|VaultFlower|PAM|1.0|checkout.scope_violation|Scope Violation Attempt|10|src=192.168.10.99 suser=unknown@company.com dhost=SRV-OT-001 outcome=blocked rt=Jan 15 2024 22:30:15 UTC requestId=a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "x_request_id": "a1b2c3d4-...",
  "related_events": [
    {
      "id": "c9d0e1f2-...",
      "source": "identity",
      "event_type": "auth.login_success",
      "event_time": "2024-01-15T22:30:14.890Z",
      "severity": "INFO"
    }
  ]
}

related_events — events sharing the same x_request_id from other databases.


GET /audit/events/export

Export audit log to CSV or JSON. Auditor and Admin only.

GET /api/v1/acme-corp/audit/events/export?source=secrets&severity=CRITICAL&from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z&format=csv
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Query parameters: Same as GET /audit/events plus:

Parameter Type Default Description
format string csv csv or json

Constraints:

  • Maximum export period: 31 days
  • If period exceeds 31 days: 400 DATE_RANGE_TOO_LARGE
  • Only one export at a time per user: 429 EXPORT_IN_PROGRESS

Response 200 — CSV:

Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="audit-secrets-2024-01-01-to-2024-01-31.csv"

id,source,event_time,event_type,severity,actor_upn,target_type,target_id,ip_address,result,x_request_id
d0e1f2a3-...,secrets,2024-01-15T22:30:15Z,checkout.scope_violation,CRITICAL,unknown@company.com,credential,e5f6a7b8-...,192.168.10.99,blocked,a1b2c3d4-...

Response 200 — JSON:

Content-Type: application/json
Content-Disposition: attachment; filename="audit-secrets-2024-01-01-to-2024-01-31.json"

Reports

GET /audit/reports/checkout-summary

Aggregated checkout statistics for a period.

GET /api/v1/acme-corp/audit/reports/checkout-summary?from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z&group_by=user
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Query parameters:

Parameter Type Required Description
from_date datetime Yes Start of period
to_date datetime Yes End of period
group_by string No user / asset / zone / system / location (default: user)

Response 200:

{
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z"
  },
  "summary": {
    "total_checkouts": 142,
    "completed": 138,
    "expired": 3,
    "revoked": 1,
    "rejected_dual_control": 2,
    "out_of_hours_access": 5,
    "critical_assets_accessed": 12,
    "access_task_count": 34,
    "rotation_task_count": 108
  },
  "breakdown": [
    {
      "group": "operator@company.com",
      "total": 23,
      "completed": 22,
      "expired": 1,
      "critical_access": 5,
      "out_of_hours": 0
    },
    {
      "group": "technician@company.com",
      "total": 18,
      "completed": 18,
      "expired": 0,
      "critical_access": 2,
      "out_of_hours": 2
    }
  ]
}

GET /audit/reports/rotation-summary

Aggregated rotation statistics and overdue tasks.

GET /api/v1/acme-corp/audit/reports/rotation-summary?from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Response 200:

{
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z"
  },
  "summary": {
    "total_rotations": 89,
    "auto_online": 45,
    "auto_domain": 12,
    "manual_task": 28,
    "emergency": 4,
    "failed": 3,
    "auto_rotation_disabled_count": 2
  },
  "overdue_tasks": [
    {
      "task_id": "uuid",
      "asset_code": "SRV-OT-001",
      "asset_name": "System1",
      "criticality_level": "CRITICAL",
      "due_date": "2024-01-10T00:00:00Z",
      "days_overdue": 5,
      "assigned_to": "operator@company.com",
      "priority": "URGENT"
    }
  ],
  "auto_rotation_disabled": [
    {
      "credential_id": "uuid",
      "asset_code": "SRV-OT-007",
      "credential_type": "LOCAL_ADMIN",
      "disabled_at": "2023-12-01T00:00:00Z",
      "disabled_by": "admin@company.com",
      "reason": "Legacy system — CISO approved exception"
    }
  ]
}

GET /audit/reports/security-alerts

Security events requiring attention.

GET /api/v1/acme-corp/audit/reports/security-alerts?from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z&severity=CRITICAL
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Query parameters:

Parameter Type Description
from_date datetime Required
to_date datetime Required
severity string WARN / CRITICAL (default: CRITICAL)

Response 200:

{
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z"
  },
  "summary": {
    "total_critical": 3,
    "total_warn": 47,
    "scope_violations": 1,
    "unusual_ip_access": 2,
    "repeated_password_views": 0,
    "mfa_blocked_users": 1,
    "out_of_hours_access": 12,
    "token_reuse_attempts": 0,
    "approval_suspicious": 0
  },
  "critical_events": [
    {
      "event_id": "uuid",
      "event_time": "2024-01-15T22:30:15Z",
      "event_type": "checkout.scope_violation",
      "actor_upn": "unknown@company.com",
      "ip_address": "192.168.10.99",
      "source": "secrets",
      "details": "Attempted access to Safety-Zone asset from OT-DMZ-North scoped user"
    }
  ]
}

GET /audit/reports/compliance

Automated compliance check against NIST SP 800-53 and FSTEC controls.

GET /api/v1/acme-corp/audit/reports/compliance?from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Response 200:

{
  "generated_at": "2024-01-15T08:00:00Z",
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z"
  },
  "checks": [
    {
      "control": "Dual Control",
      "standard": "NIST SP 800-53 AC-3(2)",
      "status": "COMPLIANT",
      "details": "100% of checkouts completed Dual Control authorization"
    },
    {
      "control": "Password Rotation",
      "standard": "FSTEC ОПС.2",
      "status": "WARNING",
      "details": "3 assets have overdue password rotation",
      "affected_assets": ["SRV-OT-001", "SRV-OT-005", "HMI-01"]
    },
    {
      "control": "Audit Log Integrity",
      "standard": "NIST SP 800-53 AU-9",
      "status": "COMPLIANT",
      "details": "No unauthorized UPDATE or DELETE grants detected on audit schemas"
    },
    {
      "control": "MFA Enforcement",
      "standard": "NIST SP 800-53 IA-2",
      "status": "COMPLIANT",
      "details": "100% of checkouts completed required MFA factors"
    },
    {
      "control": "Auto Rotation Exceptions",
      "standard": "FSTEC ОПС.2",
      "status": "WARNING",
      "details": "2 credentials have auto-rotation disabled",
      "affected_credentials": ["uuid1", "uuid2"]
    },
    {
      "control": "Separation of Duties",
      "standard": "NIST SP 800-53 AC-5",
      "status": "COMPLIANT",
      "details": "No self-assignment or self-approval violations detected"
    },
    {
      "control": "Owner Approval Coverage",
      "standard": "IEC 62443 SR 2.1",
      "status": "COMPLIANT",
      "details": "All ROTATION_TASK and ACCESS_TASK had owner approval before execution"
    }
  ],
  "overall_status": "WARNING",
  "compliant_count": 5,
  "warning_count": 2,
  "failed_count": 0
}
Status Meaning
COMPLIANT Control fully satisfied for the period
WARNING Minor issues requiring attention but not violations
FAILED Control violated — requires immediate action

GET /audit/reports/user-activity

Detailed activity report for a specific user.

GET /api/v1/acme-corp/audit/reports/user-activity?user_id=f1e2d3c4-b5a6-7890-fedc-ba0987654321&from_date=2024-01-01T00:00:00Z&to_date=2024-01-31T23:59:59Z
Authorization: Bearer {auditor_token}
X-Request-ID: {uuid}

Query parameters:

Parameter Type Required Description
user_id UUID Yes Target user
from_date datetime Yes Start of period
to_date datetime Yes End of period

Response 200:

{
  "user": {
    "upn": "operator@company.com",
    "display_name": "John Smith",
    "roles": ["Operator"]
  },
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-01-31T23:59:59Z"
  },
  "activity": {
    "logins": 22,
    "failed_logins": 1,
    "checkouts_requested": 23,
    "checkouts_completed": 22,
    "checkouts_expired": 1,
    "tasks_completed": 22,
    "tasks_failed": 0,
    "mfa_failures": 1,
    "out_of_hours_access": 0,
    "scope_violations": 0,
    "dual_control_rejections_received": 1,
    "dual_control_approvals_given": 5
  },
  "checkouts": [
    {
      "checkout_id": "uuid",
      "asset_code": "SRV-OT-001",
      "task_type": "ROTATION_TASK",
      "requested_at": "2024-01-15T08:00:00Z",
      "status": "CHECKED_IN",
      "justification": "Planned monthly maintenance of SCADA server"
    }
  ]
}

Health Check Endpoints

These endpoints do not require authentication. Used by Consul for active health checks every 10 seconds.

Base URL: https://vfw-core.contoso.com

GET /health

Liveness check — is the process alive.

GET /health

Response 200:

{
  "status": "healthy",
  "timestamp": "2024-01-15T08:00:00Z",
  "version": "1.0.0"
}

GET /health/ready

Readiness check — can the service accept traffic.

GET /health/ready

Response 200 — All dependencies healthy:

{
  "status": "ready",
  "checks": {
    "postgres_assets": "ok",
    "postgres_secrets": "ok",
    "postgres_identity": "ok",
    "rabbitmq": "ok",
    "vault": "ok",
    "consul": "ok"
  }
}

Response 503 — Dependency unavailable:

{
  "status": "not_ready",
  "checks": {
    "postgres_assets": "ok",
    "postgres_secrets": "ok",
    "postgres_identity": "ok",
    "rabbitmq": "ok",
    "vault": "sealed",
    "consul": "ok"
  }
}

GET /health/live

Process liveness with uptime.

GET /health/live

Response 200:

{
  "status": "alive",
  "uptime_seconds": 86400
}

Audit & Reporting Quick Reference

Audit Log:
  GET /audit/events                    Search all three audit logs
  GET /audit/events/{id}               Event details + CEF + related events
  GET /audit/events/export             CSV/JSON export (max 31 days)

Reports:
  GET /audit/reports/checkout-summary  Checkout statistics by group
  GET /audit/reports/rotation-summary  Rotation statistics + overdue
  GET /audit/reports/security-alerts   Security events by severity
  GET /audit/reports/compliance        NIST/FSTEC compliance status
  GET /audit/reports/user-activity     Per-user activity detail

Health (no auth):
  GET /health        Liveness
  GET /health/ready   Readiness with dependency checks
  GET /health/live    Uptime

Related Pages

Clone this wiki locally