diff --git a/docs/agents/secrets-variables.mdx b/docs/agents/secrets-variables.mdx index 14853ffc1..afab83f83 100644 --- a/docs/agents/secrets-variables.mdx +++ b/docs/agents/secrets-variables.mdx @@ -15,7 +15,7 @@ Preset agent tool calls go through a secure server-side proxy. The LLM only sees the raw expression placeholder (e.g. `${{ SECRETS.threatintel.API_KEY }}`). The actual secret values are injected server-side at the tool execution layer after the model responds, so the LLM never has access to your credentials. -`ai.action` and `ai.agent` actions do **not** support secure secrets injection. Secret and variable expressions are evaluated immediately in workflow action inputs and will be exposed to the LLM. +Do not use `SECRETS` expressions — or any expression that resolves to a value you would not send to your LLM provider — in `ai.action` or `ai.agent` inputs. Use `ai.preset_agent` for secure secrets injection. ## Secrets diff --git a/docs/audit-logs/agents.mdx b/docs/audit-logs/agents.mdx new file mode 100644 index 000000000..acf07d486 --- /dev/null +++ b/docs/audit-logs/agents.mdx @@ -0,0 +1,14 @@ +--- +title: "Organization agent logs" +description: "Export OpenTelemetry metrics, log events, and traces for agent runs to your observability backend." +--- + +This page is a work in progress. + +Agent runs export OpenTelemetry signals to your observability backend. Configure the exporter under Organization settings, then open **Agent OTel**. + +## Related pages + +- See [Organization audit logs](/audit-logs/organization) to stream user and service-account activity to your SIEM. +- See [Platform audit logs](/audit-logs/platform) to capture administration above the organization boundary. +- See [Architecture](/security/architecture) for the sandbox and gateway boundaries that agent telemetry crosses. diff --git a/docs/audit-logs/mcp-access.mdx b/docs/audit-logs/mcp-access.mdx new file mode 100644 index 000000000..0805957ca --- /dev/null +++ b/docs/audit-logs/mcp-access.mdx @@ -0,0 +1,14 @@ +--- +title: "MCP access logs" +description: "Review OAuth connections, personal access tokens, and external MCP client activity in a workspace." +--- + +This page is a work in progress. + +External MCP clients connect to Tracecat and call tools as a real user. Review their connections, tokens, and activity from the workspace sidebar under **MCP access**. + +## Related pages + +- See [Organization audit logs](/audit-logs/organization) to stream token issuance and revocation to your SIEM. +- See [Platform audit logs](/audit-logs/platform) to capture administration above the organization boundary. +- See [Architecture](/security/architecture) for the permission model behind MCP connections. diff --git a/docs/audit-logs/organization.mdx b/docs/audit-logs/organization.mdx index 7f21ff929..76ee5b4ba 100644 --- a/docs/audit-logs/organization.mdx +++ b/docs/audit-logs/organization.mdx @@ -1,12 +1,20 @@ --- title: "Organization audit logs" description: "Stream organization audit events to an HTTPS webhook and shape each request for your log collector." +keywords: ["organization audit", "audit webhook", "SIEM"] --- +import AuditDeliveryBehavior from "/snippets/audit-delivery-behavior.mdx"; +import AuditEventFields from "/snippets/audit-event-fields.mdx"; +import AuditRequestOptions from "/snippets/audit-request-options.mdx"; + Send organization audit events to an external log collector over HTTPS. You must be an organization administrator to configure the endpoint. -## Connect a log collector +Each event answers one question: which identity changed which resource, from where, and did it work. +The stream covers privilege changes, credential changes, agent configuration changes, and automation changes. + +## Configure audit logs @@ -21,28 +29,120 @@ You must be an organization administrator to configure the endpoint. - Add any headers your collector requires. You can also merge custom JSON into - every event, wrap the payload under a key such as `event`, and control TLS - certificate verification. - - - Click **Save changes**, then confirm that your collector receives an - `organization_setting` event with a `SUCCESS` status. + Set the request options your collector needs, then click **Save changes**. -## Request options +Changing the endpoint is itself an audited `organization_setting` update, so your existing collector records the change before the stream moves. +Events can continue to reach the old endpoint for up to 30 seconds after the change while cached settings expire. -| Option | Behavior | -| --- | --- | -| Audit webhook URL | Receives each event as a JSON `POST` request. | -| Custom headers | Adds static headers to every request. Header names are case-insensitive. | -| Custom payload | Merges a JSON object into every event. Custom keys replace matching default keys. | -| Payload attribute | Wraps the complete payload under the configured key. | -| Verify SSL certificate | Verifies the endpoint certificate. Disable this only for a trusted endpoint that uses a private or self-signed certificate. | +## Request options -Tracecat encrypts the webhook URL, custom headers, and custom payload at rest. -Choose custom payload keys that do not overlap default fields unless you intend to replace them. + + +## Logged events + +| Resource type | Action | Description | +| --- | --- | --- | +| `agent_catalog` | `create` | A model was added to the organization's agent catalog. | +| `agent_catalog` | `delete` | A model was removed from the organization's agent catalog. | +| `agent_catalog` | `update` | An agent catalog entry was updated. | +| `agent_custom_provider` | `create` | A custom model provider was configured. | +| `agent_custom_provider` | `delete` | A custom model provider was removed. | +| `agent_custom_provider` | `update` | A custom model provider was reconfigured. | +| `agent_model_access` | `create` | A catalog model was enabled for an organization or workspace. | +| `agent_model_access` | `delete` | A catalog model was disabled for an organization or workspace. | +| `agent_preset` | `create` | An agent preset was created. | +| `agent_preset` | `delete` | An agent preset was deleted. | +| `agent_preset` | `update` | An agent preset was updated or restored to an earlier version. | +| `agent_session` | `delete` | An agent session and its history were deleted. | +| `agent_session` | `update` | An agent session's title, preset, or MCP integrations changed. | +| `auth` | `sign_in` | A user signed in. | +| `case` | `create` | A case was created. | +| `case` | `delete` | A case was deleted. | +| `case` | `update` | A case was updated. | +| `case_comment` | `create` | A comment was added to a case. | +| `case_comment` | `delete` | A case comment was deleted. | +| `case_comment` | `update` | A case comment was edited. | +| `case_trigger` | `update` | Part of a workflow's case trigger configuration changed. | +| `case_trigger` | `upsert` | A workflow's case trigger configuration was created or replaced. | +| `mcp_personal_access_token` | `create` | An MCP personal access token was issued. | +| `mcp_personal_access_token` | `revoke` | An MCP personal access token was revoked. | +| `organization` | `delete` | An organization was deleted. | +| `organization_invitation` | `accept` | An organization invitation was accepted. | +| `organization_invitation` | `create` | An organization invitation was sent. | +| `organization_invitation` | `revoke` | An organization invitation was revoked. | +| `organization_member` | `create` | A user was added to the organization. | +| `organization_member` | `delete` | A user was removed from the organization. | +| `organization_member` | `update` | An organization member's details changed. | +| `organization_secret` | `create` | An organization secret was created. | +| `organization_secret` | `delete` | An organization secret was deleted. | +| `organization_secret` | `update` | An organization secret was updated. | +| `organization_session` | `delete` | A member's active login session was revoked. | +| `organization_setting` | `create` | An organization setting was created. | +| `organization_setting` | `delete` | An organization setting was deleted. | +| `organization_setting` | `update` | An organization setting changed, including this audit sink. | +| `rbac_assignment` | `create` | A role was assigned to a group. | +| `rbac_assignment` | `delete` | A group's role assignment was removed. | +| `rbac_assignment` | `update` | A group's role assignment changed. | +| `rbac_group` | `create` | A group was created. | +| `rbac_group` | `delete` | A group was deleted. | +| `rbac_group` | `update` | A group was updated. | +| `rbac_group_member` | `create` | A user was added to a group. | +| `rbac_group_member` | `delete` | A user was removed from a group. | +| `rbac_role` | `create` | A custom role was created. | +| `rbac_role` | `delete` | A custom role was deleted. | +| `rbac_role` | `update` | A role's scopes changed. | +| `rbac_scope` | `create` | A custom permission scope was created. | +| `rbac_scope` | `delete` | A custom permission scope was deleted. | +| `rbac_user_assignment` | `create` | A role was assigned directly to a user. | +| `rbac_user_assignment` | `delete` | A user's role assignment was removed. | +| `rbac_user_assignment` | `update` | A user's role assignment changed. | +| `schedule` | `create` | A workflow schedule was created. | +| `schedule` | `delete` | A workflow schedule was deleted. | +| `schedule` | `update` | A workflow schedule was updated. | +| `secret` | `create` | A workspace secret was created. | +| `secret` | `delete` | A workspace secret was deleted. | +| `secret` | `update` | A workspace secret was updated. | +| `service_account` | `create` | A service account was created. | +| `service_account` | `update` | A service account was renamed, re-scoped, disabled, or enabled. | +| `service_account_api_key` | `create` | An API key was issued for a service account. | +| `service_account_api_key` | `revoke` | A service account API key was revoked. | +| `table` | `create` | A lookup table was created. | +| `table` | `delete` | A lookup table was deleted. | +| `table` | `update` | A lookup table was updated. | +| `table_column` | `create` | A column was added to a lookup table. | +| `table_column` | `delete` | A column was removed from a lookup table. | +| `table_column` | `update` | A lookup table column was updated. | +| `tag` | `create` | A workflow tag was created. | +| `tag` | `delete` | A workflow tag was deleted. | +| `tag` | `update` | A workflow tag was updated. | +| `webhook` | `create` | A workflow webhook trigger was created. | +| `webhook` | `update` | A workflow webhook trigger was updated. | +| `webhook_api_key` | `create` | The first API key was issued for a webhook. | +| `webhook_api_key` | `delete` | A webhook API key was deleted. | +| `webhook_api_key` | `revoke` | A webhook API key was revoked and kept on record. | +| `webhook_api_key` | `rotate` | An existing webhook API key was replaced. | +| `workflow` | `create` | A workflow was created. | +| `workflow` | `delete` | A workflow was deleted. | +| `workflow` | `publish` | A workflow definition was published. | +| `workflow` | `update` | A workflow was updated. | +| `workflow_execution` | `cancel` | A workflow execution was cancelled and allowed to clean up. | +| `workflow_execution` | `create` | A workflow execution was started. | +| `workflow_execution` | `reset` | A workflow execution was replayed from an earlier event. | +| `workflow_execution` | `terminate` | A workflow execution was stopped immediately. | +| `workspace` | `create` | A workspace was created. | +| `workspace` | `delete` | A workspace was deleted. | +| `workspace` | `update` | A workspace was updated. | +| `workspace_invitation` | `accept` | A workspace invitation was accepted. | +| `workspace_invitation` | `create` | A workspace invitation was sent. | +| `workspace_invitation` | `revoke` | A workspace invitation was revoked. | +| `workspace_variable` | `create` | A workspace variable was created. | +| `workspace_variable` | `delete` | A workspace variable was deleted. | +| `workspace_variable` | `update` | A workspace variable was updated. | + +An organization-scoped sign-in emits `auth` `sign_in` to this sink and to the platform sink. +A superuser login that carries no organization context reaches the platform sink only. ## Event payload @@ -56,39 +156,48 @@ An audit event contains the actor, affected resource, action, result, and scope. "actor_id": "00000000-0000-4000-8000-000000000003", "actor_label": "avery@example.com", "ip_address": "192.0.2.10", + "user_agent": "Mozilla/5.0", "resource_type": "workflow", "resource_id": "00000000-0000-4000-8000-000000000004", "action": "update", "status": "SUCCESS", - "data": null, + "data": { + "changed_fields": ["title"] + }, "created_at": "2026-01-15T14:03:12.123456Z" } ``` -| Field | Description | -| --- | --- | -| `organization_id` | Organization that owns the event. | -| `workspace_id` | Workspace that owns the resource, when applicable. | -| `actor_type` | `USER` or `SERVICE_ACCOUNT`. | -| `actor_id` | ID of the user or service account that performed the action. | -| `actor_label` | User email or service account name, when available. | -| `ip_address` | Source IP address, when available. | -| `resource_type` | Type of resource affected by the action. | -| `resource_id` | ID of the affected resource, when available. | -| `action` | Operation performed on the resource. | -| `status` | `ATTEMPT`, `SUCCESS`, or `FAILURE`. | -| `data` | Additional event-specific context, when available. | -| `created_at` | UTC timestamp for the event. | + + +### Attribution + +`actor_type` distinguishes a human from automation. +`USER` events carry the account's email in `actor_label`, and `SERVICE_ACCOUNT` events carry the service account's name. + +Treat `actor_id` as the stable join key; `actor_label` is a display value that changes when a user's email changes. + +### Scope + +`organization_id` identifies the tenant and `workspace_id` identifies the workspace that owns the affected resource. +Organization-level resources such as `organization_member` and `rbac_role` have no workspace, so `workspace_id` is `null`. + +If you index platform and organization events together, filter on `organization_id` being non-null to isolate tenant activity. + +### Status lifecycle Most audited changes emit an `ATTEMPT` event followed by `SUCCESS` or `FAILURE`. -Your endpoint should return a successful response within 10 seconds; delivery failures do not block the audited action. -## Update or disconnect the endpoint +An `ATTEMPT` with no matching terminal event does not always mean the request failed — the terminal event may have been shed or lost in delivery. + +## Delivery behavior -Return to **Organization → Audit Logs** to update the request settings. -Click the disconnect button to stop sending new organization audit events. + ## Related pages -- See [Security architecture](/security/architecture) for the platform, agent, approval, and telemetry boundaries around audit events. +- See [Platform audit logs](/audit-logs/platform) to capture administration above the organization boundary. +- See [Organization agent logs](/audit-logs/agents) to export telemetry for agent runs. +- See [MCP access logs](/audit-logs/mcp-access) to review external MCP clients acting as your users. +- See [Architecture](/security/architecture) for the platform, agent, approval, and telemetry boundaries around audit events. - See [Security](/self-hosting/security) for deployment hardening guidance. diff --git a/docs/audit-logs/platform.mdx b/docs/audit-logs/platform.mdx new file mode 100644 index 000000000..7007d2074 --- /dev/null +++ b/docs/audit-logs/platform.mdx @@ -0,0 +1,108 @@ +--- +title: "Platform audit logs" +description: "Stream platform administrator actions to an HTTPS webhook and separate them from organization audit events." +keywords: ["platform audit", "superuser", "audit webhook", "SIEM"] +--- + +import AuditDeliveryBehavior from "/snippets/audit-delivery-behavior.mdx"; +import AuditEventFields from "/snippets/audit-event-fields.mdx"; +import AuditRequestOptions from "/snippets/audit-request-options.mdx"; + +Enterprise Edition + +Platform audit logs record what platform administrators do above the organization boundary. +They cover changes that no organization audit stream can see, such as a new organization, a promoted superuser, or a rewritten platform setting. + +You must be a platform superuser to configure the endpoint. These events go to their own sink, separate from every organization webhook, and organization administrators cannot read, change, or receive them. + +## Configure audit logs + + + + Open **Admin**, then select **Audit Logs** under **Platform**. + + + Click **Connect** and enter the HTTPS URL that accepts your audit events. + + + Set the request options your collector needs, then click **Save changes**. + + + +Events can continue to reach the old endpoint for up to 30 seconds after an endpoint change while cached settings expire. + +## Request options + + + +## Logged events + +| Resource type | Action | Description | +| --- | --- | --- | +| `auth` | `sign_in` | A user signed in. | +| `organization` | `create` | An organization was provisioned. | +| `organization` | `delete` | An organization was deleted. | +| `organization` | `update` | An organization was reconfigured. | +| `organization_domain` | `create` | A domain was assigned to an organization. | +| `organization_domain` | `delete` | A domain was removed from an organization. | +| `organization_domain` | `update` | An organization domain was updated. | +| `organization_invitation` | `create` | An organization invitation was sent from platform administration. | +| `organization_invitation` | `revoke` | An organization invitation was revoked from platform administration. | +| `organization_tier` | `update` | An organization's tier assignment or per-organization overrides changed. | +| `platform_registry` | `sync` | Every platform registry repository was synchronized. | +| `platform_registry_repository` | `sync` | One platform registry repository was synchronized. | +| `platform_registry_version` | `delete` | A non-current platform registry version was deleted. | +| `platform_registry_version` | `promote` | A platform registry version became the current version for its repository. | +| `platform_setting` | `update` | A platform-wide setting changed, including this audit sink. | +| `tier` | `create` | A tier definition was created. | +| `tier` | `delete` | A tier definition was deleted. | +| `tier` | `update` | A tier definition changed, altering limits for every organization on it. | +| `user` | `create` | A platform user account was created. | +| `user` | `delete` | A platform user account was deleted. | +| `user` | `demote` | Superuser access was withdrawn from a user. | +| `user` | `promote` | A user was granted superuser access. | + +An organization-scoped sign-in emits `auth` `sign_in` to this sink and to that organization's sink. +A superuser login that carries no organization context reaches this sink only. + +## Event payload + +A platform event uses the same schema as an organization event, with platform-scope identifiers left null. + +```json +{ + "organization_id": null, + "workspace_id": null, + "actor_type": "USER", + "actor_id": "00000000-0000-4000-8000-000000000003", + "actor_label": "admin@example.com", + "ip_address": "192.0.2.10", + "user_agent": "Mozilla/5.0", + "resource_type": "platform_setting", + "resource_id": null, + "action": "update", + "status": "SUCCESS", + "data": null, + "created_at": "2026-01-15T14:03:12.123456Z" +} +``` + +For platform settings updates, `data` is `null`, so the event tells you who made the change and whether it succeeded, but not which setting changed. + + + +Platform events normally carry `null` `organization_id` and `workspace_id` because Tracecat emits them with a platform role. +Organization-scoped sign-in is the exception: its `auth` `sign_in` event reaches both sinks, and the platform copy carries the organization's ID. + +Do not filter strictly on null scope to separate platform administration from tenant activity — that drops those sign-in events. +Tag each stream with a custom payload instead when both reach the same index. + +## Delivery behavior + + + +## Related pages + +- See [Organization audit logs](/audit-logs/organization) to stream user and service-account activity inside an organization. +- See [Architecture](/security/architecture) for the boundaries that platform audit events record. +- See [Self-hosted security](/self-hosting/security) for deployment hardening guidance. diff --git a/docs/docs.json b/docs/docs.json index 54dd978e5..2300a5ba1 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -96,13 +96,6 @@ "agents/secrets-variables" ] }, - { - "group": "Security", - "icon": "shield-check", - "pages": [ - "security/architecture" - ] - }, { "group": "Building custom actions", "icon": "blocks", @@ -136,10 +129,14 @@ ] }, { - "group": "Audit logs", - "icon": "logs", + "group": "Security", + "icon": "shield-check", "pages": [ - "audit-logs/organization" + "security/architecture", + "audit-logs/platform", + "audit-logs/organization", + "audit-logs/agents", + "audit-logs/mcp-access" ] } ] diff --git a/docs/security/architecture.mdx b/docs/security/architecture.mdx index cff61cd88..4493a1cd5 100644 --- a/docs/security/architecture.mdx +++ b/docs/security/architecture.mdx @@ -1,55 +1,77 @@ --- -title: Security architecture -description: "Understand how Tracecat secures the platform, AI agents, MCP tool calls, credentials, sandboxed execution, approvals, and audit data." -mode: wide +title: Architecture +description: "Understand Tracecat's threat model and security design." keywords: ["security architecture", "AI agent security", "MCP security", "sandboxing", "RBAC", "OpenTelemetry"] --- -Tracecat applies identity, policy, isolation, and audit controls outside the model so an agent cannot grant itself additional authority. -This page describes the Tracecat Cloud security profile and hardened self-hosted deployments. +Tracecat's security design rests on seven control areas: + +- Identity: SSO, SCIM provisioning, and role-based access control at organization and workspace level. +- Data security: row-level tenant isolation, encrypted credentials, and encrypted workflow payloads. +- AI agent security: default-deny tool policy, durable human approval, and token budgets. +- Sandboxed execution: nsjail isolation for custom Python, agent-generated code, and local MCP servers. +- Auditability: platform and organization audit webhooks, agent telemetry, and workspace MCP access records. +- Change management: roll back custom integrations to any commit, and review and revert workspace configuration — workflows, agents, skills, tables, and case fields — in your own Git repository. +- Dependencies: lockfile-pinned core registry dependencies, per-commit builds of custom registry dependencies, and sandboxed execution for both. + +This page covers Tracecat Cloud and hardened self-hosted deployments. + +Tracecat runs customer-authored code and agents on multi-tenant infrastructure, so every execution path is sandboxed. That code then acts with privileged access to your systems, so credentials are encrypted at rest, resolved at execution time, and attached by trusted proxies rather than handed to a model. ```mermaid flowchart LR subgraph clients["Users and triggers"] operator["User or approver"] trigger["Workflow or case trigger"] + mcpClient["External MCP client
OAuth or access token"] end subgraph control["Tracecat control plane"] - api["Tracecat API"] + api["Tracecat API and MCP endpoint"] identity["Identity · RBAC
tenant scope"] + versions["Versioned definitions
review · rollback"] temporal["Temporal
durable orchestration"] - policy["Hosted-agent policy
allow · deny · require approval"] + policy["Agent tool policy
allow · deny · require approval"] approval["Human approval
accept · reject · reason"] - audit["Approval and platform
audit events"] + audit["Platform and organization
audit events"] + mcpActivity["Workspace MCP
access activity"] end subgraph sandbox["nsjail sandbox"] - agent["Hosted agent runtime
network denied by default"] + agent["Agent runtime
network denied by default"] stdio["stdio MCP process
same sandbox and identity"] end subgraph trusted["Trusted execution services"] + runAuth["Run authorization
short-lived scoped JWTs"] tools["Tracecat API and MCP proxy"] credentials["Credential broker"] - model["Model gateway"] - otel["Scoped OTEL relay"] + llmGateway["LLM gateway"] + otel["OTLP gateway"] + payloads["Encrypted run payloads
scoped object references"] end subgraph customer["Customer-managed and external systems"] secrets["AWS Secrets Manager"] apis["Approved APIs
remote HTTP MCP"] - models["Managed or BYO model
optional LLM proxy"] + llmProviders["Managed or BYO LLM
optional LLM proxy"] + objectStore["Managed or customer
object storage"] observability["Observability or SIEM"] - auditSink["HTTPS audit webhook"] + auditSink["Platform or organization
audit webhook"] end operator --> api trigger --> api + mcpClient --> api api --> identity + api --> versions + versions --> temporal identity --> temporal identity -->|scoped policy| policy + identity -->|tenant and user scope| runAuth + policy -->|allowed tools and model| runAuth temporal --> agent + runAuth -->|short-lived JWTs| agent agent -->|tool request| policy policy -->|allowed remote tool| tools policy -->|allowed local tool| stdio @@ -58,218 +80,465 @@ flowchart LR approval -->|durable decision| temporal tools --> apis credentials --> tools - credentials --> model + credentials --> llmGateway credentials -->|resolve reference| secrets - agent --> model - model --> models - agent -. telemetry .-> otel - otel -. OTLP .-> observability + agent --> llmGateway + llmGateway --> llmProviders + temporal <-->|encrypted inputs and outputs| payloads + payloads -->|externalize large payloads| objectStore + agent -. OTLP over sandbox socket .-> otel + otel -. OTLP with tenant headers .-> observability api -. control-plane event .-> audit - approval -. one event per tool .-> audit + approval -. one event per tool decision .-> audit + api -. MCP session and tool call .-> mcpActivity audit -. HTTPS .-> auditSink ``` -## Security model +## Threat model + +This threat model covers the complete Tracecat platform. It separates conventional platform threats from AI-specific threats. -Tracecat treats prompts, retrieved context, model output, generated code, tool results, MCP servers, and client-supplied context as untrusted. -The platform enforces authorization and execution controls at trusted boundaries that the model cannot modify. +### Protected assets -The security model addresses: +- Organization and workspace data. +- Agent and automation configuration. +- User and service-account identity. +- API, OAuth, MCP, and LLM provider credentials. +- External systems reachable through tools. +- Control-plane and executor infrastructure. +- Workflow and agent inputs and outputs. +- Audit records and agent telemetry. -- Unauthorized access across organizations, workspaces, users, and service accounts. -- Agent goal hijacking, excessive agency, unsafe tool use, and approval bypass. -- Credential disclosure to models, prompts, or untrusted tool implementations. -- Unexpected code execution, resource exhaustion, and unintended network access. -- MCP and agent configuration changes that bypass review or approved policy. -- Actions that cannot be attributed to an identity, session, decision, or execution. +### Within Tracecat boundary -### Outside the Tracecat boundary +#### Platform and application threats -You remain responsible for your identity-provider policies and the security of external model providers, APIs, MCP servers, Git repositories, and observability systems. -Tracecat does not replace model evaluation, data-classification policy, prompt and content filtering, or adversarial testing. +Threat actors and untrusted sources include: + +- External attackers targeting API, authentication, OAuth, or MCP endpoints. +- Compromised tenant accounts submitting code or workloads. +- Compromised administrators, service accounts, personal access tokens, or OAuth grants. +- Malicious packages, custom registry content, and local MCP processes. +- Attackers targeting the control plane, executor, durable state, or object storage. + +Custom code runs on shared infrastructure, so isolation cannot depend on that code being correct. A logic bug, a compromised dependency, and a compromised tenant account all produce the same class of outcome: a process reading another run's data, reaching a platform service, or consuming shared capacity. The sandbox bounds all three identically, which is why the boundary does not rely on reviewing the workflow author's intent. + +| Attack surface | How an attacker can use it | Primary Tracecat controls | +| --- | --- | --- | +| Authentication and tenant access | Steal or replay user credentials.
Steal service-account credentials or personal access tokens.
Call API or MCP endpoints as the victim.
Probe identifiers from another workspace. | Authenticate before tenant resolution.
Enforce SSO and RBAC.
Scope service accounts.
Apply tenant scope and PostgreSQL row-level policies. | +| Multi-tenant code execution | Submit hostile Python, custom actions, agents, or local MCP processes.
Read files or process state.
Escape the executor.
Reach another run, tenant, or platform service. | nsjail enabled by default on full-isolation profiles.
User, process, mount, IPC, hostname, and network namespaces.
Read-only runtime and scoped mounts.
Syscall, cgroup, file, and process limits. | +| Credential and downstream access | Read stored secrets.
Capture provider credentials.
Reuse a credential outside its intended workspace or tool. | Encrypted credential storage.
Execution-time credential broker.
Short-lived JWTs scoped to the run, workspace, model, and allowed tools.
Provider credentials added by trusted services outside the sandbox. | +| OAuth and MCP access | Steal an OAuth grant or personal access token.
Use the MCP endpoint with the victim's permissions.
Hide activity across many connections. | Authenticated OAuth flows.
OAuth connections inherit the user's effective permissions.
Personal access tokens remain workspace-scoped.
Connections, tokens, and external MCP calls are visible by user. | +| Run data and durable state | Read workflow or agent inputs and outputs.
Tamper with queued work.
Use oversized payloads to expand durable history. | Application-level encryption for Temporal payloads.
Workspace-scoped encryption context.
Automatic externalization of large payloads to object storage.
Small scoped references remain in workflow state. | +| Configuration and supply chain | Publish a malicious integration.
Widen access or network policy.
Persist an unsafe workflow or agent configuration. | RBAC and platform audit events.
Versioned workflow and agent configuration.
Immutable published versions.
Custom registry rollback to any commit.
Registry lock on published workflows.
Workspace Git sync, review, and rollback. | +| Platform availability | Fork processes.
Fill storage.
Exhaust memory or CPU.
Block shared workers with long-running code. | Sandbox wall-time and CPU limits.
cgroup memory enforcement.
File-size and process-count limits.
Temporal cancellation and retry controls. | -This model follows the risk families in the [OWASP Top 10:2025](https://owasp.org/Top10/), [OWASP Top 10 for LLM Applications:2025](https://owasp.org/www-project-top-10-for-large-language-model-applications/), and [OWASP Top 10 for Agentic Applications:2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/). -The mappings below identify the most relevant categories; they do not represent certification by OWASP. +#### AI threats -Mapping prefixes identify the source list: `A` is the OWASP Top 10 for software, `LLM` is the OWASP Top 10 for LLM applications, and `ASI` is the OWASP Top 10 for agentic applications. +Threat actors and untrusted sources include: -## Identity and platform boundaries +- Attackers who control prompts, alerts, email, cases, retrieved documents, or tool results. +- Users who try to steer an agent beyond their intended task or authorization. +- Compromised LLM, API, or remote MCP providers. +- Unsafe LLM output, generated code, tool selection, or resource consumption. + +Tracecat treats the LLM as an untrusted decision-maker. It can propose a tool call and generate code. It cannot grant itself a role, approve its own call, resolve a brokered secret, or change sandbox policy. + +| Attack surface | How an attacker can use it | Primary Tracecat controls | +| --- | --- | --- | +| Agent context | Place hostile instructions in prompts or retrieved documents.
Hide instructions in alerts, email, cases, or tool results.
Redirect the agent goal.
Induce a high-impact tool call. | Default-deny tool policy.
Trusted-proxy authorization.
Human approval for selected tools.
Credentials kept outside LLM context. | +| Tools and remote MCP | Publish misleading tool metadata.
Return poisoned tool results.
Compromise a remote server to exfiltrate data or trigger unsafe actions. | Captured tool inventory.
Allow and deny policy.
Approval gates.
Trusted API and MCP proxy.
Inherited user permissions for external Tracecat MCP. | +| Generated code and `stdio` MCP | Generate shell or Python code that reads files.
Use local MCP code to consume resources.
Reach the network.
Attack the executor or another run. | The same nsjail boundary used for tenant code.
Read-only runtime and scoped mounts.
cgroup and process limits.
Default-deny agent network. | +| Secret extraction | Ask the LLM to reveal a credential.
Craft a tool request that tries to resolve or reuse another secret.
Place secret-looking instructions in untrusted content. | Execution-time credential broker.
Policy checks before resolution.
Short-lived scoped JWTs in the sandbox.
Provider credentials injected only by trusted services. | +| Human approval | Disguise the purpose of a tool call.
Mislead an approver with incomplete context.
Attempt to resume execution without an authorized decision. | Authenticated approver checks.
Temporal durable execution.
Decision bound to the run and tool call.
One audit event per tool decision. | +| Agent consumption | Loop LLM or tool calls.
Create cascading model requests.
Drive unexpected inference cost. | Total token budget.
Token burn-rate limit.
Sandbox wall-time and resource limits.
Tool policy and approval for side effects. | + +### Outside Tracecat boundary + +You own controls for systems that Tracecat does not operate. + +| Concern | Customer hardening | Suggested tools | +| --- | --- | --- | +| Identity provider | Require MFA and conditional access.
Review session and account-lifecycle policy. | [Okta](/authentication/saml#okta)
[Microsoft Entra ID](/authentication/saml#microsoft-entra-id)
[Keycloak](/authentication/saml#keycloak) | +| External LLMs | Review data use and retention.
Confirm residency and provider access.
Apply provider and endpoint allowlists. | [LLM proxy](/agents/custom-llm-providers) | +| Prompt and data filtering | Route LLM traffic through an LLM gateway.
Apply prompt-injection and content controls.
Filter PII and sensitive data. | [LLM proxy](/agents/custom-llm-providers) | +| MCP policy | Place an independent gateway around MCP traffic.
Apply an allow or deny layer.
Add inspection or consent controls. | MCP proxy | +| User audit logs | Export user and control-plane events through the [organization audit webhook](/audit-logs/organization).
Define detections and retention.
Create an incident-response process. | SIEM | +| Agent logs and traces | Export agent OTel logs and traces.
Set retention for agent telemetry.
Alert on risky tool activity and approval decisions. | OpenTelemetry-compatible LLM observability tool | +| Git change management | Require reviews and protected branches.
Sign changes to synced configuration. | GitHub
GitLab | +| Custom registry code and dependencies | Pin and review third-party dependencies.
Scan the registry repository.
Require branch protection on the registry repository. | Dependency scanning
GitHub
GitLab | +| [AI red teaming](https://research.ibm.com/blog/what-is-red-teaming-gen-AI) | Simulate adversarial attacks against the complete AI application.
Test jailbreaks and prompt injection.
Test data leakage and agentic misuse.
Retest as the system and attack techniques change. | [garak](https://github.com/NVIDIA/garak)
[PyRIT](https://github.com/microsoft/PyRIT)
[DeepTeam](https://www.trydeepteam.com/) | -OWASP mappings: `A01 Broken Access Control`, `A07 Authentication Failures`, and `ASI03 Identity and Privilege Abuse`. +Use these references to harden systems outside Tracecat: -Tracecat authenticates API and MCP requests before it resolves organization, workspace, and user context. -SSO, RBAC roles, groups, and scoped service accounts restrict which resources and operations each identity can access. +- [MCP security best practices](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices). +- [NIST Generative AI Profile](https://www.nist.gov/publications/artificial-intelligence-risk-management-framework-generative-artificial-intelligence). -The managed multi-tenant profile applies tenant scope in both the application and database layers. -PostgreSQL row-level policies provide a second boundary for organization-scoped and workspace-scoped data. +### OWASP alignment + +This page maps Tracecat controls to three OWASP risk lists: + +- [OWASP Top 10:2025](https://owasp.org/Top10/). +- [OWASP Top 10 for LLM Applications:2025](https://owasp.org/www-project-top-10-for-large-language-model-applications/). +- [OWASP Top 10 for Agentic Applications:2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/). + +The mapping identifies relevant categories. It does not represent OWASP certification. + +| Tracecat control | OWASP Top 10 | LLM applications | Agentic applications | +| --- | --- | --- | --- | +| Identity and tenant boundaries | `A01` Broken Access Control
`A07` Authentication Failures | — | `ASI03` Identity and Privilege Abuse | +| Data security | `A04` Cryptographic Failures | `LLM02` Sensitive Information Disclosure | `ASI03` Identity and Privilege Abuse | +| Default-deny tool policy | `A01` Broken Access Control | `LLM06` Excessive Agency | `ASI02` Tool Misuse and Exploitation | +| Durable approval | `A01` Broken Access Control
`A06` Insecure Design | `LLM06` Excessive Agency | `ASI02` Tool Misuse and Exploitation
`ASI09` Human-Agent Trust Exploitation | +| Sandboxed execution | `A05` Injection
`A06` Insecure Design | — | `ASI05` Unexpected Code Execution
`ASI08` Cascading Failures | +| MCP supply chain | `A03` Software Supply Chain Failures
`A08` Software or Data Integrity Failures | `LLM03` Supply Chain | `ASI04` Agentic Supply Chain Vulnerabilities | +| Token budgets | — | `LLM10` Unbounded Consumption | `ASI08` Cascading Failures | +| Audit logs | `A09` Security Logging and Alerting Failures | — | — | +| Change management | `A08` Software or Data Integrity Failures | `LLM03` Supply Chain | `ASI04` Agentic Supply Chain Vulnerabilities | +| Dependencies | `A03` Software Supply Chain Failures
`A08` Software or Data Integrity Failures | `LLM03` Supply Chain | `ASI04` Agentic Supply Chain Vulnerabilities | + +## Identity + +A01 A07 ASI03 + +Tracecat authenticates every API and MCP request before it resolves tenant context, so an unauthenticated caller never reaches a tenant lookup. Holding a valid credential establishes who you are; it does not decide what you can reach. + +### Single sign-on and provisioning + +- SAML and OIDC authenticate users against your identity provider. Basic auth is available for deployments that do not use one. +- SCIM provisions and deprovisions accounts from the directory, so access is removed at the source when someone leaves. +- SCIM also syncs directory groups to Tracecat groups, which is what makes group-based role assignment worth using. + +See [SAML SSO](/authentication/saml) and [OIDC](/authentication/oidc) for connection steps. + +### Role-based access control + +A scope is one permission on one resource, named `resource:action` following OAuth 2.0 convention. The prefix carries the level: + +| Level | Scope shape | Example | +| --- | --- | --- | +| Workspace | `resource:action` | `workflow:read`, `agent:create` | +| Organization | `org:resource:action` | `org:member:invite`, `org:rbac:update` | -Tracecat encrypts sensitive settings and stored credentials at rest and supports application-level encryption for Temporal payloads. -Production traffic uses TLS in transit. +Roles bundle scopes: + +- Built-in roles cover the common cases: `organization-owner`, `organization-admin`, `organization-member`, `workspace-admin`, `workspace-editor`, `workspace-viewer`. +- You can define custom roles, and custom scopes alongside the platform-defined set, when the built-in roles do not fit. + +Roles are assigned to a group or directly to a user. Each assignment is either organization-wide or bound to a single workspace, and a user's effective permission is the union of both. That means an organization-wide assignment applies in every workspace, while a workspace assignment grants nothing outside it. + +Service accounts are scoped directly rather than through roles, and are bounded two ways: they can only hold scopes from an allowlist for their kind, and nobody can grant a service account a scope they do not themselves hold. + +## Data security + +A04 + +### Tenant isolation + +Tenant scope is enforced in the application layer and again by PostgreSQL row-level security on tenant-owned tables. The second layer is the one that matters under failure: a missed application check does not by itself return another tenant's rows. + +### Credentials and sensitive settings + +Tracecat presents stored credentials to external systems at execution time, so credential storage has to be reversible. Anything that never needs replaying is stored one-way instead. + +Reversible encryption uses Fernet, which is AES-128-CBC with an HMAC-SHA256 authentication tag, keyed by `TRACECAT__DB_ENCRYPTION_KEY`. Ciphertext is authenticated, so tampering fails to decrypt rather than yielding altered plaintext. It covers: + +- Workspace, organization, and platform secrets. +- OAuth and integration credentials, including access tokens, refresh tokens, and client secrets. +- Remote MCP server headers and `stdio` MCP environment variables. +- Custom LLM provider credentials and Slack agent-channel credentials. +- Organization and platform settings marked sensitive, including the audit webhook URL, its headers, and its custom payload. + +API tokens are not encrypted, because Tracecat never needs to read one back: + +- Service account API keys, MCP personal access tokens, and webhook API keys are stored as a salted BLAKE2b digest. Tracecat verifies a presented token in constant time and cannot recover the original. +- The raw token is returned exactly once, at creation. Only a short preview prefix is kept so you can identify it later. +- A lost token is replaced by rotation, never by retrieval. + + + **Credentials in MCP commands and URLs are stored in cleartext** + + The `stdio` MCP command and its arguments, and the remote MCP server URI, are + not encrypted. Put credentials in environment variables or headers, which are, + rather than inline in an argument or a query string. + + +### Workflow payloads and durable state + +Temporal persists workflow and agent inputs and outputs for the life of an execution history, so payload protection is separate from database encryption. + +- Payloads are encrypted with AES-256-GCM by a Tracecat-side codec before Temporal stores anything, so Temporal only ever holds ciphertext. +- Each workspace gets a distinct key, derived with HKDF-SHA256 from a versioned root secret using the workspace ID as derivation context. One workspace's key does not decrypt another's payloads. +- The keyring is versioned. Rotation issues a new key ID, and existing histories stay readable under the ID they were written with. +- Secret values are masked as `***` in action results, and masking runs before the result is persisted, so history holds the masked form. +- Large triggers and action results move to object storage automatically. Workflow state keeps a scoped reference, which bounds how much data one run pushes through durable history. + +Two limits are worth knowing. Masking is literal substring replacement, so an encoded or otherwise transformed copy of a secret is not caught. Payload encryption is a deployment setting (`TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED`) that is off by default — enable it wherever Temporal history can hold sensitive data. + +### Encryption keys + +Tracecat generates no key material of its own. You provision two things and supply them to the deployment: `TRACECAT__DB_ENCRYPTION_KEY`, the Fernet key behind credential encryption, and the Temporal payload keyring behind workflow history encryption. + +Store both in the secret manager your platform already provides, and keep them out of application configuration and version control. On Kubernetes, the recommended production deployment, use a Kubernetes Secret synced from your own secret manager by External Secrets Operator rather than one created by hand. + +On AWS Fargate, use AWS Secrets Manager: ECS injects the core secrets into the container at task launch, and the task role fetches the keyring at runtime so it never appears in a task definition. + +On Docker Compose, treat the `.env` file as the sensitive artifact: restrict it to the service account that runs Tracecat and keep it out of version control. Move to Kubernetes for a managed secret store and the full sandbox boundary. + + + **`TRACECAT__DB_ENCRYPTION_KEY` cannot be rotated** + + Tracecat encrypts under a single Fernet key and has no re-encryption path. + Changing or losing the key makes every stored credential unrecoverable. Back + it up, and restrict access to it at least as tightly as the credentials it + protects. + + +See [Platform secrets](/self-hosting/security#platform-secrets) for per-deployment storage and rotation, and [Secrets management](/self-hosting/kubernetes#secrets-management) for the Helm wiring. ### External secrets -OWASP mappings: `A04 Cryptographic Failures`, `LLM02 Sensitive Information Disclosure`, and `ASI03 Identity and Privilege Abuse`. +A04 LLM02 ASI03 + +The subsections above cover how credentials are stored. This one covers how a value reaches running code, and the boundary differs between workflow actions and agents. + +Tracecat stores credential metadata and resolves values at execution time, in trusted services only: + +- The executor, for the secrets a workflow action declares. +- The agent tool runner, for secret expressions in tool arguments. +- The trusted MCP server, which resolves remote HTTP MCP headers per call. +- The LLM gateway, which attaches provider credentials per request. +- The preset service, for `stdio` MCP environment values. + +None of these services runs inside the agent sandbox, and no credential value is persisted in workflow state. You can keep workspace and integration credentials in AWS Secrets Manager instead of Tracecat. -You can keep workspace and integration credential values in AWS Secrets Manager. -Tracecat stores the credential metadata and resolves the referenced value at execution time through the credential broker. +#### Workflow actions -For brokered API, remote HTTP MCP, and model calls, the model receives a typed interface rather than the downstream credential, and only the trusted proxy receives the resolved value. -Credentials for a local `stdio` MCP process are an exception because that process shares the agent sandbox; treat them as accessible to agent-controlled code. +An action receives the secrets it declares or references, injected into its sandbox at dispatch. The sandbox bounds what the action can reach — the host, the database, other runs — rather than hiding the credential from code that needs it. + +`core.script.run_python` receives no ambient workspace secrets. Your script sees only what you pass through `env_vars` or Action inputs. + +See [Secrets](/automations/core-concepts/secrets) for how actions declare and reference secrets. + +#### Agents + +Agent-controlled code runs in the same sandbox as the agent, so any credential placed inside that sandbox is readable by whatever the model generates. Tracecat keeps credential values out of the agent sandbox. + +- The sandbox receives short-lived JWTs scoped to the run, workspace, model, and allowed tools. +- Trusted services validate those claims before resolving a provider credential. +- Trusted proxies attach credentials to API, LLM, and remote HTTP MCP calls outside the sandbox. +- The LLM receives typed interfaces and results; Tracecat never places a stored credential value into model context. Secret expressions in tool arguments resolve outside the sandbox, after the model responds. + +Local `stdio` MCP is the exception. Its credentials enter the shared sandbox, so treat them as readable by agent-controlled code. ## Agent and MCP control plane ### Default-deny tool policy -OWASP mappings: `A01 Broken Access Control`, `LLM06 Excessive Agency`, and `ASI02 Tool Misuse and Exploitation`. +A01 LLM06 ASI02 -Hosted agents apply the same deterministic policy boundary to Tracecat tools, remote MCP tools, and sandboxed `stdio` MCP tools. -An agent can discover only tools that its identity, workspace, agent configuration, and tool policy allow. +Hostile instructions hidden in an alert, email, case, or tool result can redirect an agent toward a tool the operator never intended it to call. -An explicit deny takes precedence over an allow. -Tracecat rechecks brokered Tracecat and remote HTTP MCP invocations at the trusted proxy, so calling a hidden or stale remote tool directly does not bypass policy. -Local `stdio` MCP is instead constrained to the tool inventory captured by the runtime and the shared sandbox boundary. +Tool selection is therefore not the model's decision to make. Agents discover only the tools allowed by identity and workspace scope, and agent configuration narrows that set further. An explicit deny overrides an allow. -A policy decision has one of three results: +Every policy decision resolves to one of three outcomes: -- `Allow`: Execute the tool through the trusted proxy or isolated `stdio` process. -- `Deny`: Return a blocked result without resolving credentials or causing a side effect. -- `Require approval`: Pause before execution and create a durable approval request. +- `Allow`: Run the tool through the trusted proxy or `stdio` process. +- `Deny`: Block the call before credentials resolve or side effects occur. +- `Require approval`: Create a durable request and pause before execution. -Tracecat bounds each hosted-agent run at the sandbox boundary with wall-time and resource limits. -These controls contain loops and cascading failures without assuming a fixed number of model requests or tool calls. +The trusted proxy rechecks Tracecat and remote HTTP MCP calls before executing them, so a request the agent fabricates is rejected outside the sandbox rather than trusted because it arrived. Local `stdio` MCP is checked against the captured inventory only and does not get this second check. - - Coming soon: Per-run token budgets and token burn-rate limits will complement the sandbox boundary. A total token budget will bound worst-case inference cost, while the burn-rate limit will control how quickly long-running agents consume that budget. Tool policy and human approvals will continue to govern side-effect risk separately. - +### Token budget + +LLM10 ASI08 + +An agent stuck in a reasoning loop, or steered into one, can issue model requests until it exhausts your inference budget. A fixed cap on LLM requests or tool calls does not contain this, because legitimate multi-step work has no predictable call count. + +Tracecat bounds consumption by tokens instead: + +- `Total token budget`: Caps cumulative LLM token usage for the run. +- `Token burn-rate limit`: Caps how fast the run consumes that budget, which stops runaway loops before the total is spent. + +Sandbox wall-time and resource limits contain execution independently, and tool policy and approval continue to govern side effects. ### Durable human approval -OWASP mappings: `A01 Broken Access Control`, `A06 Insecure Design`, `LLM06 Excessive Agency`, `ASI02 Tool Misuse and Exploitation`, and `ASI09 Human-Agent Trust Exploitation`. +A01 A06 LLM06 ASI02 ASI09 + +An approval gate only holds if the decision survives worker restarts and retries, and if no other path can resume the tool without a recorded decision. -Tracecat uses Temporal durable execution to persist an agent at the approval boundary. -The tool does not execute until an authorized approver accepts the request. +Temporal persists the agent at the approval boundary and the tool waits for an authorized acceptance. The decision stays attached to the run and tool call across retries and worker restarts, and Tracecat authorizes the call only when the recorded decision permits it. -The same approval decision remains attached to the run across retries, worker restarts, and time spent waiting. -Tracecat does not authorize the tool until the recorded decision permits it. -For authenticated UI and API decisions, Tracecat emits one audit event per tool with the approver, decision time, source, tool identifiers, accepted or rejected result, override indicator, and optional bounded, pattern-filtered denial reason. +Each authenticated accept or reject emits one audit event identifying the approver, the tool, and the outcome. Tool arguments, override values, prompts, and tool outputs are never included. ### External MCP connections -OAuth connections to Tracecat MCP inherit the authenticated user's effective Tracecat permissions. -Personal access tokens remain workspace-scoped. +External MCP clients such as coding agents authenticate to Tracecat and call tools with a real user's authority, which makes connection sprawl an access-review problem. -The MCP access page groups OAuth connections and personal access tokens by user and shows tool calls made through external MCP connections. -Tracecat does not currently narrow an MCP profile below the user's inherited scopes; fine-grained per-profile scope reduction is planned. +- OAuth connections inherit the user's effective Tracecat permissions. +- Personal access tokens remain workspace-scoped. +- The MCP access page groups connections, tokens, and external tool calls by user. +- Per-profile scope reduction below user permissions is planned. ## Trusted agent execution -OWASP mappings: `A05 Injection`, `A06 Insecure Design`, `ASI05 Unexpected Code Execution`, and `ASI08 Cascading Failures`. +A05 A06 ASI05 ASI08 -The secure execution profile runs hosted agent runtimes, agent-generated code, and local MCP processes inside nsjail boundaries. -The agent sandbox exposes only the files, processes, and broker interfaces required for the run. -General automation actions follow the network policy of their configured executor. +Custom Python actions, agents, agent-generated code, and local MCP processes all execute code that Tracecat did not write, on infrastructure shared between tenants. Containment therefore cannot depend on that code being correct. + +nsjail is the boundary. It runs by default on full-isolation profiles and applies to tenant code, third-party packages, and generated output alike. The sandbox exposes only the files and broker interfaces the run needs. General automation actions use their configured executor network policy instead. | Layer | Control | | --- | --- | -| Network | Each hosted-agent sandbox receives an isolated network namespace with no direct route by default. Model and tool requests use trusted brokers; direct internet access requires an explicit agent setting. | -| Identity and processes | Workloads run without host or platform-service identity. The agent and its `stdio` child processes share the sandbox execution identity and private runtime state. | -| Namespaces | User, process, mount, IPC, hostname, and network namespaces separate the workload from the executor and neighboring runs. | -| Filesystem | The runtime and dependencies are read-only. Each run receives scoped mounts, bounded temporary storage, and an isolated writable working directory. | -| Kernel boundary | Syscall filtering blocks kernel-facing operations that the workload does not need after sandbox creation. The process cannot add privileges from inside the jail. | -| Resources | cgroup v2 limits aggregate sandbox memory. CPU time, wall time, file size, open files, and process counts are also bounded. | -| Lifecycle | Tracecat terminates the complete sandbox process tree on cancellation or timeout and removes per-run state after execution. | +| Network | Isolated network namespace.
No direct route by default.
LLM and tool requests use trusted brokers.
Direct internet access requires an explicit agent setting. | +| Identity and processes | No host or platform-service identity.
The agent and `stdio` children share one sandbox identity. | +| Namespaces | User and process namespaces.
Mount and IPC namespaces.
Hostname and network namespaces. | +| Filesystem | Read-only runtime and dependencies.
Scoped mounts and bounded temporary storage.
Isolated writable working directory. | +| Kernel boundary | Syscall filtering blocks unnecessary kernel operations.
The process cannot add privileges from inside the jail. | +| Resources | cgroup v2 bounds aggregate memory.
CPU and wall-time limits.
File-size and open-file limits.
Process-count limits. | +| Lifecycle | Cancellation and timeout terminate the sandbox process tree.
Tracecat removes per-run state after execution. | -These controls limit the blast radius of compromised model output or third-party code. -They do not make untrusted code safe to run outside a supported sandbox profile. +These controls bound the blast radius of compromised output or third-party code. They do not make untrusted code safe outside a supported sandbox profile. ### Sandboxed MCP -OWASP mappings: `A03 Software Supply Chain Failures`, `A08 Software or Data Integrity Failures`, `LLM03 Supply Chain`, and `ASI04 Agentic Supply Chain Vulnerabilities`. +A03 A08 LLM03 ASI04 -Tracecat separates remote and local MCP execution: +A third-party MCP server is untrusted code with a tool description attached. Where it runs decides what it can reach. -- Remote MCP servers run outside the agent sandbox. The trusted Tracecat proxy resolves authentication, calls the approved server, and returns the result. -- `stdio` MCP servers run as child processes inside the agent sandbox and inherit its filesystem, network, time, resource, and identity boundaries. +Remote MCP servers run outside the agent sandbox, and the trusted proxy authenticates each call and returns the result. `stdio` MCP servers run as child processes inside the agent sandbox and inherit its filesystem, network, time, resource, and identity boundaries. -Tracecat captures the approved MCP server and tool inventory for the run, and normal SDK-dispatched calls are limited to that inventory. -Because agent-controlled code and `stdio` MCP share one sandbox, local MCP is not a separate tool-policy isolation boundary against code that invokes the local executable directly; use remote HTTP MCP when calls must be rechecked at the trusted proxy. +Local MCP is a containment boundary, not a policy boundary. Agent-generated code inside the sandbox can invoke a local server's executable directly. Use remote HTTP MCP when every call must be rechecked at the trusted proxy. - `stdio` MCP currently has four security-model limitations. Approval gates do not support `stdio` tools, so use remote HTTP MCP for tools that require human approval. Configuring `stdio` also requires network access for the whole agent sandbox, not only the child process. The agent and `stdio` process share one sandbox and execution identity rather than separate identities. Credentials required by a `stdio` server are materialized inside that shared sandbox and must be treated as accessible to agent-controlled code. + **`stdio` MCP limitations** + + - Approval gates do not support `stdio` tools. Use remote HTTP MCP for approved calls. + - Enabling `stdio` requires network access for the whole agent sandbox. + - The agent and `stdio` process share one execution identity. + - `stdio` credentials enter the shared sandbox. -### Trusted API and model gateways +### Trusted API and LLM gateways -For brokered API, remote HTTP MCP, and model calls, the secure preset-agent path keeps secret values out of model context and the agent sandbox. -Tracecat evaluates secret references only after the model produces a permitted tool or model request, then its built-in API and MCP proxy adds the downstream API, OAuth, MCP, or model credential outside the sandbox. -The agent receives the typed result, not the credential. +A credential pasted into a prompt is a credential in model context, in provider logs, and in any telemetry that captures prompts. -You can use Tracecat's managed model gateway or configure an OpenAI-compatible provider and BYO model. -The customer provider can route requests through an LLM proxy without changing the agent's tool boundary. +Tracecat resolves secrets referenced by preset-agent Expressions only after a request passes policy, and adds API, OAuth, MCP, and LLM credentials at the proxy outside the sandbox. The agent receives the typed result rather than the credential. + +You can use the managed LLM gateway, an OpenAI-compatible provider, or route LLM traffic through your own proxy. - Do not place credentials directly in prompts or in `ai.action` and `ai.agent` inputs. Use a preset agent and server-side secret references when the model must not receive the resolved value. + **Keep credentials out of agent inputs** + + - Do not place credentials directly in prompts or agent inputs. + - Use Tracecat Expressions to reference secrets in preset-agent instructions. -See [Secrets and variables](/agents/secrets-variables) for the secure preset-agent path and its limitations. +See [Secrets and variables](/agents/secrets-variables) to learn how to pass secrets securely to preset agents through Expressions. -## Auditability and change control +## Audit logs -OWASP mappings: `A09 Security Logging and Alerting Failures`, `LLM10 Unbounded Consumption`, and `ASI08 Cascading Failures`. +A09 -Tracecat separates user-centric platform audit events from full hosted-agent runtime telemetry. +Tracecat separates audit signals by administrative scope and runtime source. -| Signal | Coverage | Destination | -| --- | --- | --- | -| Platform audit events | Authenticated actor, request source, resource, action, and result for supported control-plane operations. Approval submissions produce one event per tool with the approver and decision time. | Your configured HTTPS audit webhook. Tracecat does not store a separate copy of the emitted webhook stream. | -| MCP access activity | OAuth connections and personal access tokens grouped by user, plus tool calls made through external Tracecat MCP connections. | The MCP access page. | -| Agent OpenTelemetry | Hosted-agent logs, traces, and metrics correlated to the organization, workspace, session, and run, including tool activity and Tracecat approval-decision events. | Your OTLP-compatible observability backend. | +| Log | Produced by | Where it goes | Use it to answer | +| --- | --- | --- | --- | +| [Platform audit logs](/audit-logs/platform) | Platform administrators acting above any organization | Platform-scoped HTTPS webhook, separate from every organization sink | Who changed platform settings, users, organizations, tiers, or the registry? | +| [Organization audit logs](/audit-logs/organization) | Users and service accounts, scoped to an organization and workspace | Organization HTTPS webhook | Who changed this resource, from where, and did it succeed? | +| [Organization agent logs](/audit-logs/agents) | Agent runs inside the sandbox | OTLP export through the trusted gateway | Which models, tools, and approvals did the agent use? | +| [MCP access logs](/audit-logs/mcp-access) | External MCP clients calling Tracecat as a user | Workspace MCP access page | Which client invoked which tool as which user, and did it succeed? | + + + Audit events record operations, not content. -The scoped OTEL relay accepts telemetry from the sandbox without exposing the destination credential to the agent runtime. -You control which backend receives it and how that system filters, retains, and alerts on the data. + - `data` carries only stable identifiers, changed-field names, boolean state flags, counts, and a small set of operation discriminators. Tracecat drops unrecognized keys, and drops an allowed field when its value matches a credential pattern. + - Prompts, tool arguments, tool outputs, credentials, and resource contents never appear in an audit event. + - `actor_label`, `ip_address`, and `user_agent` are modeled as separate fields, so you can apply your own retention policy to them. + - Use [Organization agent logs](/audit-logs/agents) when you need prompt, tool, or model-level detail. + -Native model-runtime tool telemetry captures the initial tool decision, which can be an interruption while Tracecat waits for approval. -Tracecat emits a complementary approval-decision event for the later human accept or reject result. +## Change management -Platform approval audit events cover authenticated Tracecat UI and API users and exclude raw tool arguments, override values, credentials, prompts, and outputs. -Slack-originated approval actor events are not included yet, and audit webhook delivery remains best-effort so a slow or unavailable collector cannot delay or roll back a decision. +A08 LLM03 ASI04 -### Workspace Git sync +A configuration change persists beyond the session that made it, so an account compromise can outlive the access that caused it. -Use Workspace Git sync to move agent and automation configuration through your existing Git change-management process. -Tracecat supports customer-owned GitHub and GitLab repositories so you can review changes, apply branch protection, and promote approved configuration from staging to production. +### Actions registry -Git history complements platform audit logs by recording the reviewed configuration that entered each environment. -Runtime authorization still comes from Tracecat RBAC and policy, not from repository access alone. +A custom registry rolls back to any commit: each sync creates an immutable version identified by the source commit, and you can sync to any commit or promote any earlier version from the UI or the API. Tracecat blocks deletion of a version that published workflows still reference. -## Deployment profiles +Rollback is predictable for workflows you publish in Tracecat. Publishing records a registry lock mapping each registry origin to the version current at publish time, and every execution resolves actions from that lock, so neither a sync nor a rollback changes what the published workflow runs. -| Profile | Isolation contract | Intended use | -| --- | --- | --- | -| Tracecat Cloud | Tracecat manages the secure agent profile, trusted brokers, network boundary, sandbox lifecycle, and supported Enterprise controls. | Managed production workloads. | -| Self-hosted Kubernetes | The Helm deployment supports nsjail and cgroup-backed isolation when you apply the required executor security context and capacity settings. | Self-hosted production workloads that run untrusted code or agents. | -| AWS Fargate | Fargate does not provide the kernel capabilities required by nsjail. Tracecat uses a reduced-isolation executor profile. | Trusted workloads that must run on Fargate. Use Kubernetes when you require the full sandbox boundary. | -| macOS or Windows development | The direct backend provides development process isolation without the Linux nsjail boundary. | Local development with trusted code only. | +Workflows imported through workspace sync carry no registry lock, so every execution resolves their actions against the current registry version. Republish an imported workflow in Tracecat to pin it. + + + Republish a workflow to adopt newly synced actions, even when the workflow itself has not changed. Imported workflows are not pinned until you republish them. + + +The core registry tracks the Tracecat release version and updates when you upgrade Tracecat. Earlier core versions stay available to workflows that pinned them. + +See [Custom registry](/custom-actions/custom-registry) for repository setup, sync, and commit selection. + +### Workspace GitOps + +Workspace sync exports workflows, agent presets, skills, tables, case tags, case fields, case dropdowns, case durations, and variables to a GitHub or GitLab repository you own. Secrets sync as key names only — values never leave Tracecat. + +```mermaid +flowchart LR + staging["Staging workspace
author and test"] -->|export as pull request| pr["Pull request"] + pr --> review["Your Git repository
review · branch protection · signing"] + review -->|merge| main["Default branch"] + main -->|pull pinned commit| prod["Production workspace
separate workspace RBAC"] +``` + +- Build and test in a staging workspace, then export the workspace as a pull request. +- Review in your Git repository, where branch protection and signing apply. +- Merge to your default branch. +- Pull that commit into the production workspace. +- Use workspace-level RBAC so the people who author in staging are not the people who pull into production. + +Every pull targets an explicit commit, so imports are reproducible and rollback is a pull of an earlier commit. Tracecat does not pull in the background — to automate promotion, call the sync API from your CI/CD pipeline with a service account. + + + A pull reproduces workspace configuration, not action versions. Imported workflows carry no registry lock, so each execution resolves actions against the target workspace's current core and custom registry versions until you publish the workflow there. + + +## Dependencies -See [Self-hosted security](/self-hosting/security) for backend selection and [Kubernetes](/self-hosting/kubernetes#security) for the hardened deployment requirements. +A03 A08 LLM03 ASI04 -## Further hardening +Core registry dependencies resolve from a committed lockfile that pins exact versions, and the executor runs that resolved set. The same dependency tree runs on every executor. -Tracecat provides enforcement at its control-plane and execution boundaries. -Add independent controls when your risk model requires defense in depth: +Custom registry dependencies are yours. Tracecat resolves them from your repository's `pyproject.toml` at sync time and builds the result into the version artifact for that commit — it does not pin, scan, or review them on your behalf. -- Route model traffic through your LLM proxy to apply prompt firewalls, content policy, PII or DLP filtering, model allowlists, and provider-level budgets. -- Place your MCP proxy in front of Tracecat MCP or between Tracecat and a downstream MCP server for an additional allow, deny, inspection, or consent layer. -- Export agent OTEL data and platform audit events to your observability or SIEM platform, then define customer-specific detections, retention, and incident response. -- Red-team agents before production and after changes to prompts, models, skills, tools, or MCP servers. Test goal hijacking, tool misuse, poisoned context, approval manipulation, and cross-tool data exposure. +Custom registry code runs in the same sandbox as core actions, at sync and at execution. The sandbox bounds what a compromised dependency can reach without making it safe. + +Pin your dependencies, review changes in the registry repository, and apply the same branch protection you use for production code. + +See [Custom registry](/custom-actions/custom-registry) for how to declare dependencies in your registry repository's `pyproject.toml`. + +## Deployment profiles + +| Profile | Isolation contract | Intended use | +| --- | --- | --- | +| Tracecat Cloud | Tracecat manages the secure agent profile and trusted brokers.
Tracecat also manages the network boundary and sandbox lifecycle. | Managed production workloads. | +| Self-hosted Kubernetes | Helm supports nsjail and cgroup-backed isolation.
Apply the required executor security context and capacity settings. | Production workloads that run untrusted code or agents. | +| AWS Fargate | Fargate lacks the kernel capabilities required by nsjail.
Tracecat uses a reduced-isolation executor profile. | Trusted Fargate workloads.
Use Kubernetes for the full sandbox boundary. | +| macOS or Windows development | The direct backend lacks the Linux nsjail boundary. | Local development with trusted code only. | -Review the [MCP security best practices](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices) and the [NIST Generative AI Profile](https://www.nist.gov/publications/artificial-intelligence-risk-management-framework-generative-artificial-intelligence) when you define these controls. +- See [Self-hosted security](/self-hosting/security) to select an execution backend. +- See [Kubernetes](/self-hosting/kubernetes#security) for the sandboxing and authentication settings the chart expects. ## Related pages -- See [AI agent](/agents/ai-agent) to configure tools, MCP servers, approvals, request bounds, and network access. -- See [Secrets and variables](/agents/secrets-variables) to keep credential values out of preset-agent model context. -- See [MCP servers](/automations/integrations/mcp-integrations) to connect remote and sandboxed `stdio` servers. -- See [Custom LLM providers](/agents/custom-llm-providers) to route agents through a customer model or LLM gateway. -- See [Organization audit logs](/audit-logs/organization) to stream platform audit events to your log collector. -- See [Self-hosted security](/self-hosting/security) to select and harden an execution backend. +- See [AI agent](/agents/ai-agent) to configure tools, approvals, and network access. +- See [Secrets and variables](/agents/secrets-variables) to keep credentials out of LLM context. +- See [MCP servers](/automations/integrations/mcp-integrations) to connect remote or `stdio` servers. +- See [Custom LLM providers](/agents/custom-llm-providers) to route agents through your LLM gateway. +- See [Platform audit logs](/audit-logs/platform) to stream platform administrator events. +- See [Organization audit logs](/audit-logs/organization) to stream organization user events. +- See [Organization agent logs](/audit-logs/agents) to export agent telemetry. +- See [MCP access logs](/audit-logs/mcp-access) to investigate workspace MCP activity. +- See [Self-hosted security](/self-hosting/security) to harden an execution backend. diff --git a/docs/self-hosting/environment-variables.mdx b/docs/self-hosting/environment-variables.mdx index 89b0c61e1..90c72d9c3 100644 --- a/docs/self-hosting/environment-variables.mdx +++ b/docs/self-hosting/environment-variables.mdx @@ -11,8 +11,8 @@ import EnvironmentVariables from "/snippets/environment-variables.mdx"; | :----- | :------ | | `TRACECAT__DB_ENCRYPTION_KEY` | Fernet key for at-rest encryption in PostgreSQL. Losing it makes encrypted credentials unrecoverable. | | `TRACECAT__SERVICE_KEY` | HMAC key for service-to-service JWT signing. | -| `TRACECAT__SIGNING_SECRET` | Signs webhook URLs and HMAC operations. Changing it invalidates existing webhook URLs. | -| `USER_AUTH_SECRET` | Signs OAuth state parameters and password-reset tokens. | +| `TRACECAT__SIGNING_SECRET` | Signs webhook URLs and HMAC operations. Changing it invalidates existing webhook URLs and agent channel endpoint URLs. | +| `USER_AUTH_SECRET` | Secures password reset tokens, email verification tokens, and OAuth state. Derives the MCP OIDC issuer keypair and the internal OIDC client secret. | Generate all four with `openssl`: diff --git a/docs/self-hosting/security.mdx b/docs/self-hosting/security.mdx index 7b28de8df..f103f4c9f 100644 --- a/docs/self-hosting/security.mdx +++ b/docs/self-hosting/security.mdx @@ -34,17 +34,64 @@ services: In production, consider replacing self-hosted PostgreSQL and Redis with managed services (e.g., Amazon RDS, ElastiCache) that handle encryption at rest, automated backups, and credential rotation. -## Execution sandboxing +## Platform secrets -Tracecat executes user-defined Python scripts and actions inside the executor service. The level of isolation depends on your configuration. +Tracecat requires four cryptographic secrets, plus an optional keyring if you enable Temporal payload encryption. + +| Secret | Protects | +| --- | --- | +| `TRACECAT__DB_ENCRYPTION_KEY` | Fernet key for credentials and sensitive settings stored in PostgreSQL. | +| `TRACECAT__SERVICE_KEY` | Service-to-service JWT signing. | +| `TRACECAT__SIGNING_SECRET` | Webhook URL signing and HMAC operations. | +| `USER_AUTH_SECRET` | Password reset tokens, email verification, OAuth state, the MCP OIDC issuer keypair, and the internal OIDC client secret. | +| `TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING` | Versioned keyring for Temporal payload encryption. Optional, and only read when `TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED` is true. | + + + +### Where to store them + +Keep these out of your application configuration and out of version control. Use the mechanism your platform already provides. + +| Deployment | Recommended storage | +| --- | --- | +| [AWS ECS Fargate](/self-hosting/aws-fargate) | AWS Secrets Manager. Pass secret ARNs to Terraform; values are resolved at task launch and never appear in your `.tfvars`. | +| [Kubernetes](/self-hosting/kubernetes#secrets-management) | External Secrets Operator syncing from your secret manager, or an existing Kubernetes Secret you create out of band. | +| [Docker Compose](/self-hosting/docker-compose) | A `.env` file on the host. Restrict it to the service account that runs Tracecat and exclude it from version control. | + +On Kubernetes, prefer External Secrets Operator over a hand-created Secret. Your secret manager stays the source of truth, values are re-synced rather than copied, and no plaintext passes through a shell history or a manifest. Reserve chart-managed secret templates for pipelines that encrypt values at rest with Sealed Secrets or SOPS. + +### Rotation + +Rotation support differs by secret, and the differences matter before you plan a rotation window. - By default, Tracecat runs with `TRACECAT__DISABLE_NSJAIL=true` and uses the `direct` executor backend. In this mode, scripts run as regular subprocesses and can access the executor's environment variables, filesystem, and network. This is acceptable for development but **not recommended for production**. + **`TRACECAT__DB_ENCRYPTION_KEY` cannot be rotated** + + Tracecat encrypts under a single Fernet key with no re-encryption path. + Changing it makes every stored credential unrecoverable, and there is no + migration to re-key existing rows. Treat this key as permanent for the life of + the deployment: back it up, and control access to it at least as tightly as + the credentials it encrypts. -### PID namespace isolation +| Secret | Overlap window | Rotation procedure | Blast radius | +| --- | --- | --- | --- | +| `TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING` | Yes | Add a key and point `current_key_id` at it. Keep retired keys as long as their histories are retained. | None. Existing histories stay readable under the key they were written with. | +| `TRACECAT__SIGNING_SECRET` | No | Rotate, then reissue every affected URL. | Every webhook URL and agent channel endpoint URL. Breaks in-flight Slack OAuth installs, and pending Slack approval buttons for up to 24 hours. | +| `TRACECAT__SERVICE_KEY` | No | Restart every service that holds it in one window, including `ui`, which uses it for the SAML ACS proxy. | While services disagree, in-flight agent turns fail their next tool or LLM call, executor calls fail, and service-to-service requests return `401`. Miss `ui` and SSO login breaks. | +| `USER_AUTH_SECRET` | No | Restart `api` and `mcp` together. | Active MCP access tokens (1-hour lifetime), and in-flight password reset and verification links. Sessions are database-backed, so users are not logged out. MCP refresh tokens are hashed and survive. | + +## Isolation + +Tracecat executes user-defined Python scripts, custom actions, and agents inside the executor service. You choose between nsjail isolation and no isolation. + +Defaults differ by deployment target. -The default `direct` backend provides best-effort PID namespace isolation using Linux `unshare`. This prevents scripts from inspecting other processes via `/proc`, but does not restrict filesystem or network access. It works without Docker privileged mode and is the baseline for non-sandboxed deployments. +| Deployment | Default | +| --- | --- | +| [Kubernetes](/self-hosting/kubernetes#security) | nsjail sandbox. The chart applies the required security context to the executor pods. | +| [Docker Compose](/self-hosting/docker-compose) | No isolation. `TRACECAT__DISABLE_NSJAIL=true` with the `direct` backend. | +| [AWS Fargate](/self-hosting/aws-fargate) | No isolation. Fargate cannot grant the capabilities nsjail requires. | ### nsjail sandbox (recommended for production) @@ -68,15 +115,23 @@ nsjail requires: - The nsjail binary and sandbox rootfs (included in Tracecat images) - nsjail is not supported on macOS or Windows. These platforms can only use the `direct` backend with PID namespace isolation. + nsjail is not supported on macOS or Windows. Use the `direct` backend on those platforms. +### No isolation + +Without nsjail, scripts, custom actions, and agents run as regular subprocesses in the executor. + +This is a supported production configuration when you trust everything that runs. That means your own workflow and custom registry code, the third-party dependencies those actions install, and the agents, tools, and MCP servers you enable. + +Review that code and pin those dependencies as you would any code with direct access to your systems. Choose nsjail instead when you run code you have not reviewed, such as untrusted third-party packages or agents that generate and execute their own code. + ### Choosing a backend | Backend | Isolation | Latency | Use case | | :------ | :-------- | :------ | :------- | -| `direct` | PID namespace only | ~50ms | Development, trusted environments | -| `ephemeral` | nsjail sandbox (cold per action) | ~4000ms | Production, maximum isolation | +| `direct` | None | ~50ms | Trusted code, dependencies, and agents | +| `ephemeral` | nsjail sandbox (cold per action) | ~4000ms | Untrusted code, dependencies, and agents | ## Authentication @@ -88,4 +143,4 @@ Never run production traffic over plain HTTP. See [TLS and certificates](/self-h ## Related pages -- See [Security architecture](/security/architecture) for the platform and AI agent trust model. +- See [Architecture](/security/architecture) for the platform and AI agent trust model. diff --git a/docs/self-hosting/tls.mdx b/docs/self-hosting/tls.mdx index bc79f3a79..6492db286 100644 --- a/docs/self-hosting/tls.mdx +++ b/docs/self-hosting/tls.mdx @@ -172,7 +172,7 @@ To make every service trust your CA — including custom LLM providers and Pytho - The injected bundle does not reach actions running inside the [nsjail sandbox](/self-hosting/security#execution-sandboxing) (`TRACECAT__EXECUTOR_SANDBOX_ENABLED=true`). + The injected bundle does not reach actions running inside the [nsjail sandbox](/self-hosting/security#isolation) (`TRACECAT__EXECUTOR_SANDBOX_ENABLED=true`). The sandbox strips these environment variables and does not mount `/custom-ca`. For sandboxed HTTP actions, use the per-action `ca_cert` secret instead. diff --git a/docs/snippets/audit-delivery-behavior.mdx b/docs/snippets/audit-delivery-behavior.mdx new file mode 100644 index 000000000..379fddf2a --- /dev/null +++ b/docs/snippets/audit-delivery-behavior.mdx @@ -0,0 +1,9 @@ +Tracecat posts each event as a JSON `POST` request and does not block the audited action on the result. + +- Delivery runs in the background, so a failing or slow collector does not prevent the audited change from completing. +- Each request times out after 10 seconds. +- Tracecat makes up to three delivery attempts per event — the initial request plus two retries with exponential backoff — on `429`, `500`, `502`, `503`, `504`, and transport errors. Other `4xx` responses are terminal. +- A retry after a lost response can deliver a duplicate. Events carry no event ID and a retried event is byte-identical, so deduplicate on the full event body if you need exact counts. +- Under sustained backpressure Tracecat sheds events rather than buffering without bound. + +Delivery is best-effort, so do not treat the stream as a guaranteed-complete ledger. diff --git a/docs/snippets/audit-event-fields.mdx b/docs/snippets/audit-event-fields.mdx new file mode 100644 index 000000000..0979b329c --- /dev/null +++ b/docs/snippets/audit-event-fields.mdx @@ -0,0 +1,15 @@ +| Field | Description | +| --- | --- | +| `organization_id` | Organization scope. `null` on platform events, except the platform copy of an organization-scoped `auth` `sign_in`, which carries the organization's ID. | +| `workspace_id` | Workspace that owns the affected resource, when applicable. | +| `actor_type` | `USER` or `SERVICE_ACCOUNT`. | +| `actor_id` | Stable ID of the user or service account that performed the action. | +| `actor_label` | User email or service-account name, when available. | +| `ip_address` | Source IP address, when available. | +| `user_agent` | Bounded client user-agent string, when available. | +| `resource_type` | Type of resource affected by the action. | +| `resource_id` | Stable ID of the affected resource, when available. | +| `action` | Operation performed on the resource. | +| `status` | `ATTEMPT`, `SUCCESS`, or `FAILURE`. | +| `data` | Privacy-bounded operational metadata, when available. | +| `created_at` | UTC event timestamp. | diff --git a/docs/snippets/audit-request-options.mdx b/docs/snippets/audit-request-options.mdx new file mode 100644 index 000000000..4d9c881ae --- /dev/null +++ b/docs/snippets/audit-request-options.mdx @@ -0,0 +1,25 @@ +| Option | Behavior | +| --- | --- | +| Audit webhook URL | Receives each event as a JSON `POST` request. | +| Custom headers | Adds static headers to every request. Header names are case-insensitive. | +| Custom payload | Merges a JSON object into every event. Custom keys replace matching default keys. | +| Payload attribute | Wraps the complete payload under the configured key. | +| Verify SSL certificate | Verifies the endpoint certificate. Disable this only for a trusted endpoint that uses a private or self-signed certificate. | + +Tracecat encrypts the webhook URL, custom headers, and custom payload at rest. + +Use the payload attribute when your collector expects the event under a specific key. Splunk HTTP Event Collector is the common case: it requires each event wrapped in an `event` field. + +Set the payload attribute to `event`, and Tracecat wraps the whole payload: + +```json +{ + "event": { + "actor_label": "avery@example.com", + "resource_type": "workflow", + "action": "update", + "status": "SUCCESS", + "created_at": "2026-01-15T14:03:12.123456Z" + } +} +``` diff --git a/docs/snippets/generate-secrets.mdx b/docs/snippets/generate-secrets.mdx index 517258cc0..9721c1e60 100644 --- a/docs/snippets/generate-secrets.mdx +++ b/docs/snippets/generate-secrets.mdx @@ -7,7 +7,7 @@ openssl rand -hex 32 # Signing secret (hex, 32 bytes) — used for webhook URL signing and HMAC operations openssl rand -hex 32 -# User auth secret (hex, 32 bytes) — used for OAuth state and password reset tokens (API only) +# User auth secret (hex, 32 bytes) — used for password reset, email verification, OAuth state, and OIDC key derivation openssl rand -hex 32 # DB encryption key (Fernet-compatible base64, 32 bytes) — used for encrypting secrets at rest @@ -16,5 +16,7 @@ openssl rand 32 | base64 | tr -d '\n' | tr '+/' '-_' Store these securely. Losing `TRACECAT__DB_ENCRYPTION_KEY` makes encrypted credentials unrecoverable. - Losing `TRACECAT__SIGNING_SECRET` invalidates existing webhook URLs. + Losing `TRACECAT__SIGNING_SECRET` invalidates existing webhook URLs and agent channel endpoint URLs. + +See [Where to store them](/self-hosting/security#where-to-store-them) for the recommended storage on each deployment target, and which of these secrets can be rotated.