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

ParameterTypeDescription
from_dateISO 8601Start of the reporting window (optional)
to_dateISO 8601End of the reporting window (optional)
include_recommendationsbooleanInclude 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

ParameterTypeDescription
event_typestringFilter by type: auth.login, auth.logout, member.added, role.changed, data.exported, etc.
severitystringFilter: low, medium, high, critical
from_dateISO 8601Events from this date
to_dateISO 8601Events until this date
user_idUUIDFilter events by acting user
session_idstringFilter events by session
limitintegerMax results (default: 50, max: 1000)
offsetintegerPagination 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

StatusMeaning
201 CreatedAudit event recorded; the full record is returned
400 Bad RequestValidation error: missing/invalid field (e.g. unknown action or severity, malformed resource_id)
401 UnauthorizedAuthentication required or invalid
403 ForbiddenCaller lacks the required audit permission or active membership
500 Internal Server ErrorUnexpected server error

Security Alerts

List Alerts

GET /v1/security/alerts

The organization is resolved from the authenticated session.

Query Parameters

ParameterTypeDescription
alert_typestringFilter by alert type
statusstringFilter: active, acknowledged, resolved, false_positive
severitystringFilter: low, medium, high, critical
from_dateISO 8601Alerts from this date
to_dateISO 8601Alerts until this date
limitintegerMax results (default: 25, max: 100)
offsetintegerPagination 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

StatusMeaning
201 CreatedAlert created in open status; the full record is returned
400 Bad RequestValidation error: missing required field (alert_type, severity, title) or invalid value
401 UnauthorizedAuthentication required or invalid
403 ForbiddenCaller lacks the required permission or active membership
500 Internal Server ErrorUnexpected 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

ParameterTypeDescription
from_dateISO 8601Start of the reporting window (optional)
to_dateISO 8601End 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

ParameterTypeDescription
resource_typestringFilter by resource type
resource_idUUIDFilter by resource
rule_typestringFilter: allow or deny
scopestringFilter: global, org, user, role, group, department, project, org_hierarchy
limitintegerMax results (max: 100)
offsetintegerPagination 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

StatusMeaning
201 CreatedVisibility rule created; the full record is returned
400 Bad RequestValidation error: missing/invalid field, or an invalid scope / scope_id combination (scope_id must be null for global and present otherwise)
401 UnauthorizedAuthentication required or invalid
403 ForbiddenCaller lacks admin/owner role or ownership of the target resource
500 Internal Server ErrorUnexpected server error

Delete Visibility Rule

DELETE /v1/visibility/rules/:id