Audit Trail
Every secret access, token issuance, and approval decision is permanently logged. Query, export, and integrate audit data for compliance, incident response, and anomaly detection.
Why audit logs matter
Agent systems access credentials continuously and autonomously. Without an audit trail, you have no way to answer: who read this secret, when, from where, and why?
Agent Secret Store captures every vault interaction as an immutable audit event — including denied requests, expired token attempts, and approval decisions. Events are written to an append-only log and cannot be modified or deleted by any API call.
Event types
Every audit event has an event field in resource.action format.
| Event | Actor | Description |
|---|---|---|
| secret.created | human/agent | A new secret was stored in the vault |
| secret.updated | human/agent | Secret value or metadata was modified |
| secret.rotated | system/human | Secret was rotated; new version activated |
| secret.imported | human/agent | Multiple secrets were imported into a namespace |
| secret.read | agent/token | A secret value was retrieved |
| secret.deleted | human/agent | A secret was permanently deleted |
| token.issued | agent | A scoped token was issued |
| token.revoked | human | A token was explicitly invalidated before expiry |
| approval.requested | agent | An agent requested approval for a sensitive/critical secret |
| approval.granted | human | Approver accepted a pending token request |
| approval.denied | human | Approver rejected a pending token request |
| approval.expired_cleanup | system | Expired approval requests were cleaned up |
| agent.created | human | A new agent key was issued |
| agent.updated | human | Agent scopes, namespaces, or IP policy changed |
| tenant.profile_updated | human | Tenant profile settings were updated |
Audit event data model
Each event is a JSON object with a stable schema. The metadata field carries event-specific context (e.g. scope for token events, version for secret events):
{
"id": "7b8c2e8f-2ff5-4d9e-ae1f-d8c12ab42b4d",
"event_type": "secret.read",
"actor_id": "b4f5d0b3-7b55-44fb-9210-f7a06f3587c1",
"actor_type": "token",
"resource_type": "secret",
"resource_id": "6d3454f7-6db0-4123-8b35-c09304a0271f",
"metadata": {
"namespace": "production/gemini",
"key": "GEMINI_API_KEY",
"version": 3,
"scope_used": "secrets:read:production/gemini/*"
},
"ip_address": "10.0.1.50",
"user_agent": "agentsecretstore-python/1.2.0",
"created_at": "2026-06-01T14:22:31.847Z"
}| Field | Type | Description |
|---|---|---|
| id | uuid | Globally unique event ID |
| event_type | string | Event type in resource.action format |
| actor_id | uuid | ID of the principal that triggered the event |
| actor_type | string | Principal category such as user, agent, token, or system |
| resource_type | string | Affected resource category such as secret, token, agent, approval, or tenant |
| resource_id | uuid | null | ID of the affected resource when available |
| metadata | object | Event-specific key-value context |
| ip_address | string | null | Source IP address of the request |
| user_agent | string | null | Client user agent |
| created_at | string | ISO-8601 timestamp in UTC |
Querying the audit trail
Query events with filters: event type, actor ID, resource type, resource ID, and time range. Results are paginated with a maximum of 100 events per page.
Python
import os
from datetime import datetime, timedelta, timezone
import httpx
async def query_audit_trail():
start_time = (datetime.now(timezone.utc) - timedelta(hours=24)).isoformat()
async with httpx.AsyncClient(base_url="https://api.agentsecretstore.com") as client:
response = await client.get(
"/v1/audit",
headers={"Authorization": f"Bearer {os.environ['FIREBASE_ID_TOKEN']}"},
params={
"event_type": "secret.read",
"start_time": start_time,
"limit": 100,
},
)
response.raise_for_status()
for event in response.json()["events"]:
metadata = event.get("metadata", {})
print(event["created_at"], event["actor_id"], metadata.get("namespace"), metadata.get("key"))TypeScript
const token = process.env.FIREBASE_ID_TOKEN!;
const params = new URLSearchParams({
event_type: 'secret.read',
resource_type: 'secret',
start_time: new Date(Date.now() - 3600_000).toISOString(),
limit: '100',
});
const response = await fetch('https://api.agentsecretstore.com/v1/audit?' + params, {
headers: { Authorization: 'Bearer ' + token },
});
if (!response.ok) throw new Error(await response.text());
const { events } = await response.json();
if (events.length > 100) {
console.warn('Unusual spike: ' + events.length + ' secret reads in the last hour');
}curl
# List recent events — newest first
curl https://api.agentsecretstore.com/v1/audit \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-G \
--data-urlencode "event_type=secret.read" \
--data-urlencode "start_time=2026-06-01T00:00:00Z" \
--data-urlencode "limit=50"
# Filter by resource type
curl https://api.agentsecretstore.com/v1/audit \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-G \
--data-urlencode "resource_type=secret"
# Export to CSV (response is CSV content)
curl https://api.agentsecretstore.com/v1/audit/export \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Accept: text/csv" \
-G \
--data-urlencode "start_time=2026-06-01T00:00:00Z" \
-o audit-export.csvRetention per plan
Audit events are queryable via API for the retention window of your plan. After that window, events are moved to cold storage (BigQuery) and remain accessible via the dashboard export.
| Plan | Hot (API queryable) | Cold (BigQuery) | Total |
|---|---|---|---|
| Free | 24 hours | — | 24 hours |
| Pro | 90 days | 2 years | ~2.25 years |
| Enterprise | 365 days | Configurable (up to 7 years) | Custom |
CSV export
Export filtered audit events as CSV for spreadsheet analysis, compliance submissions, or SIEM ingestion. The export API accepts the same filter parameters as the query API.
The CSV includes all event fields plus flattened metadata columns. Downloads are streamed — large exports (millions of rows) won't time out.
Scheduled exports
Enterprise tenants can configure a weekly or monthly audit export delivered to an S3 bucket or GCS bucket. Configure in Settings → Compliance → Scheduled Exports.
Compliance queries
Common audit queries for SOC 2, HIPAA, and incident response:
# SOC 2 evidence: all secret reads in Q1 2026
curl https://api.agentsecretstore.com/v1/audit/export \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Accept: text/csv" \
-G \
--data-urlencode "event_type=secret.read" \
--data-urlencode "resource_type=secret" \
--data-urlencode "start_time=2026-01-01T00:00:00Z" \
--data-urlencode "end_time=2026-03-31T23:59:59Z" \
-o soc2-q1-critical-access.csv
# HIPAA audit: all reads by a specific agent in a date range
curl https://api.agentsecretstore.com/v1/audit/export \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Accept: text/csv" \
-G \
--data-urlencode "actor_id=4b3d06fa-6ad4-48b8-9dfd-27e6fbb8794c" \
--data-urlencode "start_time=2026-01-01T00:00:00Z" \
-o hipaa-agent-audit.csv
# Incident investigation: everything that happened to a known secret UUID
curl https://api.agentsecretstore.com/v1/audit \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-G \
--data-urlencode "resource_type=secret" \
--data-urlencode "resource_id=6d3454f7-6db0-4123-8b35-c09304a0271f" \
--data-urlencode "start_time=2026-05-01T00:00:00Z"SOC 2 Type II
- ›All access to production secrets
- ›Approval decisions with timestamps
- ›Member role changes
- ›Token issuances with scope
HIPAA
- ›PHI-adjacent credential access
- ›Agent identity tied to reads
- ›Access denied events
- ›Key rotation history
Incident Response
- ›All reads of compromised key
- ›Actor IPs at time of breach
- ›Token history for actor
- ›Timeline reconstruction
Approval Workflows →
Require human sign-off before sensitive secrets are read.
Compliance Roadmap →
SOC 2, GDPR, HIPAA, and PCI-DSS plans for Agent Secret Store.
Security Best Practices →
Least-privilege design, IP allowlisting, anomaly monitoring.
REST API Reference →
Full audit query and export endpoint documentation.