Security & Compliance
Monitor security posture, review audit events, manage alerts, and access compliance artifacts. Public endpoints are available for SBOM and security contact information.
Security Dashboard
GET /v1/security Retrieve an aggregated security overview for the authenticated user’s organization, including open alerts, recent audit events, compliance status, and risk score. The organization is resolved from the session.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
from_date | ISO 8601 | Start of the reporting window (optional) |
to_date | ISO 8601 | End of the reporting window (optional) |
include_recommendations | boolean | Include generated security recommendations (optional) |
Response
{
"data": {
"overview": {
"health_score": 85,
"period_start": "2026-03-13T00:00:00Z",
"period_end": "2026-04-12T00:00:00Z"
},
"alerts": {
"critical": 0,
"high": 1,
"medium": 2,
"low": 0,
"total": 3
},
"metrics": {
"total_events": 1204
},
"recommendations": []
}
}
The health score starts at 100 and is reduced by open critical, high, and
medium alerts in the reporting window. recommendations is
populated only when include_recommendations is set.
Audit Events
List Audit Events
GET /v1/security/audit/events The organization is resolved from the authenticated session.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
event_type | string | Filter by type: auth.login, auth.logout, member.added, role.changed, data.exported, etc. |
severity | string | Filter: low, medium, high, critical |
from_date | ISO 8601 | Events from this date |
to_date | ISO 8601 | Events until this date |
user_id | UUID | Filter events by acting user |
session_id | string | Filter events by session |
limit | integer | Max results (default: 50, max: 1000) |
offset | integer | Pagination offset |
Response
{
"data": {
"events": [
{
"id": "...",
"event_type": "role.changed",
"severity": "high",
"actor_id": "...",
"actor_email": "admin@example.com",
"target_id": "...",
"description": "Role changed from member to admin",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 ...",
"metadata": {...},
"created_at": "2026-04-12T15:30:00Z"
}
],
"pagination": {
"total": 1204,
"limit": 50,
"offset": 0,
"has_more": true
}
}
} Create Audit Event
POST /v1/security/audit/events Manually log an audit event. Use this for custom application events that should appear in the organization’s audit trail. The organization and acting user are resolved from the authenticated session.
Request Body
{
"event_type": "data.exported",
"action": "export",
"outcome": "success",
"severity": "low",
"resource_type": "project_report",
"resource_id": "...",
"details": {
"format": "pdf",
"record_count": 150
}
}
The organization and acting user (actor_id) are taken from the
authenticated session. System-assigned fields (id,
created_at) are never supplied in the request body; they are
assigned by the platform; any actor or organization value in the payload is ignored.
Response
Returns the full created audit-event record on success.
{
"success": true,
"data": {
"id": "...",
"org_id": "...",
"event_type": "data.exported",
"action": "export",
"actor_id": "...",
"severity": "low",
"resource_type": "project_report",
"resource_id": "...",
"details": {
"format": "pdf",
"record_count": 150
},
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 ...",
"created_at": "2026-04-13T10:00:00Z"
}
} Response Codes
| Status | Meaning |
|---|---|
201 Created | Audit event recorded; the full record is returned |
400 Bad Request | Validation error: missing/invalid field (e.g. unknown action or severity, malformed resource_id) |
401 Unauthorized | Authentication required or invalid |
403 Forbidden | Caller lacks the required audit permission or active membership |
500 Internal Server Error | Unexpected server error |
Security Alerts
List Alerts
GET /v1/security/alerts The organization is resolved from the authenticated session.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
alert_type | string | Filter by alert type |
status | string | Filter: active, acknowledged, resolved, false_positive |
severity | string | Filter: low, medium, high, critical |
from_date | ISO 8601 | Alerts from this date |
to_date | ISO 8601 | Alerts until this date |
limit | integer | Max results (default: 25, max: 100) |
offset | integer | Pagination offset |
Create Alert
POST /v1/security/alerts The organization is resolved from the authenticated session.
Request Body
{
"alert_type": "unusual_login_location",
"title": "Unusual login location detected",
"severity": "high",
"description": "Login from unrecognized IP address in a new country",
"risk_score": 72,
"metadata": {
"ip_address": "198.51.100.23",
"country": "XX",
"user_id": "..."
}
}
System-assigned fields (id, status,
created_at) are never supplied in the request body; they are
assigned by the platform. A new alert is always created in open status.
Response
Returns the full created alert record on success.
{
"success": true,
"data": {
"id": "...",
"org_id": "...",
"alert_type": "unusual_login_location",
"severity": "high",
"title": "Unusual login location detected",
"description": "Login from unrecognized IP address in a new country",
"source": null,
"actor_id": null,
"resource_type": null,
"resource_id": null,
"status": "open",
"metadata": {
"ip_address": "198.51.100.23",
"country": "XX",
"user_id": "..."
},
"created_at": "2026-04-13T10:00:00Z"
}
} Response Codes
| Status | Meaning |
|---|---|
201 Created | Alert created in open status; the full record is returned |
400 Bad Request | Validation error: missing required field (alert_type, severity, title) or invalid value |
401 Unauthorized | Authentication required or invalid |
403 Forbidden | Caller lacks the required permission or active membership |
500 Internal Server Error | Unexpected server error |
Update Alert
PUT /v1/security/alerts/:id Request Body
{
"status": "acknowledged",
"resolution_notes": "Verified with user, legitimate travel login"
} Security Metrics
GET /v1/security/metrics The organization is resolved from the authenticated session.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
from_date | ISO 8601 | Start of the reporting window (optional) |
to_date | ISO 8601 | End of the reporting window (optional) |
Returns aggregated security metrics for the reporting window: the total audit-event count and the total and currently active security-alert counts. The default window is the last 30 days.
Response
{
"data": {
"period": { "from": "2026-03-13T00:00:00Z", "to": "2026-04-12T00:00:00Z" },
"audit_events": { "total": 1204 },
"security_alerts": { "total": 3, "active": 2 }
}
} Public Endpoints
The following endpoints do not require authentication.
SBOM
GET /v1/security/sbom.json Returns a CycloneDX Software Bill of Materials in JSON format. This provides transparency into the dependencies used by the platform.
Security Contact
GET /v1/security/security.txt
Returns the security.txt file following RFC 9116. Contains
contact information, encryption keys, and vulnerability disclosure policy.
Visibility
Visibility rules control content-level visibility of individual resources to users, groups, roles, departments, and projects. This is separate from RBAC permissions. The organization is resolved from the authenticated session.
Check Visibility
POST /v1/visibility/check Check whether a given target can see a specific resource.
Request Body
{
"resource_type": "document",
"resource_id": "...",
"target_user_id": "...",
"target_group_id": "..."
} List Visibility Rules
GET /v1/visibility/rules Query Parameters
| Parameter | Type | Description |
|---|---|---|
resource_type | string | Filter by resource type |
resource_id | UUID | Filter by resource |
rule_type | string | Filter: allow or deny |
scope | string | Filter: global, org, user, role, group, department, project, org_hierarchy |
limit | integer | Max results (max: 100) |
offset | integer | Pagination offset |
Create Visibility Rule
POST /v1/visibility/rules Request Body
{
"resource_type": "document",
"resource_id": "...",
"scope": "group",
"scope_id": "...",
"rule_type": "allow"
} scope_id is required for every scope except global.
The organization and the rule’s creator are taken from the authenticated
session. System-assigned fields (id, created_at) are never
supplied in the request body; they are assigned by the platform.
Response
Returns the full created visibility rule on success.
{
"success": true,
"data": {
"id": "...",
"org_id": "...",
"resource_type": "document",
"resource_id": "...",
"scope": "group",
"target_id": "...",
"created_by_user_id": "...",
"created_at": "2026-04-13T10:00:00Z"
}
} Response Codes
| Status | Meaning |
|---|---|
201 Created | Visibility rule created; the full record is returned |
400 Bad Request | Validation error: missing/invalid field, or an invalid scope / scope_id combination (scope_id must be null for global and present otherwise) |
401 Unauthorized | Authentication required or invalid |
403 Forbidden | Caller lacks admin/owner role or ownership of the target resource |
500 Internal Server Error | Unexpected server error |
Delete Visibility Rule
DELETE /v1/visibility/rules/:id