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. Events your applications report have types beginning with custom. |
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
}
}
} Record an Application Event
POST /v1/security/audit/events
Record an event reported by one of your own applications in the
organization’s audit trail, so that actions happening outside Backbuild
sit beside the ones Backbuild records. Requires the
Write Audit Events permission (audit.write),
which organization owners and administrators hold and which you can add to a
custom role. Viewing the audit trail does not grant it.
A reported event is always recognizable as reported. Its
event_type (and resource_type, if you send one) is
in the custom. namespace, which Backbuild’s own events never
use, and its details.origin is caller_reported.
The acting user and organization come from your session. The event’s
own ip_address, user_agent and
session_id are the ones Backbuild observed for the request that
reported it; the address, user agent and session you send describe the event
you are reporting (for example your end user’s) and are stored as
claimed, under details.claimed. Sign-in events
(login, logout) are recorded by Backbuild only and
cannot be reported.
Request Body
| Field | Type | Description |
|---|---|---|
event_type | string | Required. custom. followed by one or more dot-separated names of lowercase letters, digits and _, at most 100 characters (for example custom.crm.record_exported) |
action | string | Required. One of create, update, delete, state_change, access, import, export |
outcome | string | Required. 1 to 50 lowercase letters, digits or _ (for example success) |
severity | string | Required. low, medium, high or critical |
risk_score | number | Optional. 0 to 100 |
target_user_id | UUID | Optional. The user the event concerns |
resource_type | string | Optional. The affected resource’s type, in the custom. namespace |
resource_id | UUID | Optional. The affected resource |
details | object | Optional. Event data, at most 64 KB as JSON |
metadata | object | Optional. Additional data, at most 64 KB as JSON |
expires_at | ISO 8601 | Optional |
ip_address | string | Optional. The IPv4 or IPv6 address the event concerns (no prefix length). Stored as claimed |
user_agent | string | Optional. The user agent the event concerns, at most 1024 characters, with no control or invisible formatting characters. Stored as claimed |
session_id | string | Optional. The session the event concerns in your application’s own terms: 1 to 128 letters, digits and . _ : -. Stored as claimed |
{
"event_type": "custom.crm.record_exported",
"action": "export",
"outcome": "success",
"severity": "low",
"resource_type": "custom.crm.report",
"resource_id": "...",
"ip_address": "198.51.100.23",
"details": {
"format": "pdf",
"record_count": 150
}
} Response
Returns the stored audit-event record.
{
"success": true,
"data": {
"id": "...",
"org_id": "...",
"event_type": "custom.crm.record_exported",
"action": "export",
"actor_id": "...",
"actor_type": "user",
"resource_type": "custom.crm.report",
"resource_id": "...",
"details": {
"origin": "caller_reported",
"reporter": { "credential": "session" },
"reported": {
"outcome": "success",
"severity": "low",
"details": { "format": "pdf", "record_count": 150 }
},
"claimed": { "ip_address": "198.51.100.23" }
},
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 ...",
"session_id": "...",
"request_id": "...",
"created_at": "2026-04-13T10:00:00Z"
}
} Response Codes
| Status | Meaning |
|---|---|
201 Created | Event recorded; the stored record is returned |
400 Bad Request | Validation error: a missing or invalid field, an event_type or resource_type outside the custom. namespace, or an action other than the seven listed |
401 Unauthorized | Authentication required or invalid |
403 Forbidden | Caller lacks the Write Audit Events 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. Requires the
Create Security Alert permission
(security_alert.create), which organization owners and
administrators hold and which you can add to a custom role.
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 Create Security Alert 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