Integration surfaces
Execution-engine and LLM-gateway runtime APIs are internal platform surfaces. Do not call them from external bots or customer integrations.
Auth model for integrations
The public control-plane API is session-based. Browser clients use the sameSameSite=Lax session cookie as the management console. Mutating requests with a session cookie, plus password login and signup before a session exists, must echo the CSRF token in x-csrf-token.
AcornOps v1 does not expose a public PAT or broad bot service-account credential for the control-plane API. Installed external integration clients authenticate with raw bearer tokens whose SHA-256 hashes are configured in EXTERNAL_INTEGRATION_CLIENTS_JSON.
For v1 integrations, keep privileged decisions attributable:
- use outgoing webhooks for bot notifications and the authorized Workflow API for launches; AcornOps does not currently expose an inbound webhook-to-Workflow trigger,
- require an explicit linked-user confirmation before submitting a write approval,
- send users to the management console for approvals outside the integration’s own troubleshooting runs or Workflow executions and for management actions,
- never auto-approve because a webhook or run event was received.
create_read_write_runs to a registered external integration client’s allowed capabilities and the linked user’s workspace grant. That lets the integration request read-write troubleshooting runs and active read-write or approval-gated Workflows when the linked user’s workspace role also allows it. Write-capable tools still pause on AcornOps approval gates. The exact integration link and client recorded on the run or Workflow execution may submit the linked user’s explicit approval or rejection. It cannot decide approvals for browser-created executions, another link/client, schedules, or system triggers.
Internal service tokens such as ORCH_SERVICE_TOKEN, EXECUTION_ENGINE_DISPATCH_TOKEN, and LLM_GATEWAY_ADMIN_TOKEN are platform credentials. External integration client bearer tokens are narrow adapter credentials, not public PATs. The built-in MCP bridge uses the run-scoped JWT minted for the active execution.
External integration account-link endpoints
AcornOps exposes a narrow external integration account-link contract for an external integration client. External integration client-side command handling, message copy, event handling, retries, and channel behavior belong outside AcornOps. The integration client can use:POST /api/v1/auth/external-integrations/linkwithAuthorization: Bearer <external-integration-client-token>and body{ "externalUserId": "<external-user-id>", "externalDisplayName": "<optional-safe-name>" }to create a short-lived browser link.POST /api/v1/auth/external-integrations/resolvewith the same bearer token and body{ "externalUserId": "<external-user-id>" }to resolve whether the external identity islinkedorunlinked.POST /api/v1/auth/external-integrations/revokewith the same bearer token and body{ "externalUserId": "<external-user-id>" }to revoke the integration client’s durable link for that external user.
linkUrl under /integrations/external/link. The user opens that URL within the token TTL, and the console shows the normal AcornOps login page when no browser session exists. After password or OIDC sign-in establishes a browser session, the console calls POST /api/v1/auth/external-integrations/link/preview to show safe pending-link metadata and grantable workspaces. The console calls POST /api/v1/auth/external-integrations/link/complete only after the user explicitly approves the external account and selected workspace grants. Signed-in users can list, edit workspace grants for, and unlink their own active external links through the user-owned external integration endpoints.
Linked bot requests are authorized per workspace. Effective permissions are the linked AcornOps user’s workspace role intersected with the registered integration client’s capability ceiling and the user’s saved workspace grant. A workspace without a grant is hidden or denied to the external integration.
Workflow executions started by an external integration retain the registered client display name for operator-facing provenance in AcornOps. Exact execution responses returned to the integration keep the existing restricted representation and do not expose that browser-only provenance or internal request identity.
External integration clients should not store browser cookies, OIDC tokens, raw link tokens, or an AcornOps user ID as authorization material. Browser login and link completion are AcornOps-owned session flows, not external integration APIs.
Linked Workflow access
An installed external client can list and run a deliberately narrow set of Workflows for a linked user. Send both the installed client bearer token and the external identity observed from the provider:read_workspace_data, create_sessions, and the run
capability required by the Workflow, plus every other Workflow permission.
Active ungated read-only definitions require create_read_only_runs. Active
read-write or approval-gated definitions require the deployment-owned client
ceiling and user grant to opt into create_read_write_runs. AcornOps still
applies Workflow compilation, catalog readiness, Agent tool inheritance,
signed target-tool routing, tool narrowing, and approval gates.
The external client may use:
GET /api/v1/workspaces/{workspaceId}/workflowsto list eligible definitions.GET /api/v1/workflows/{workflowId}?workspaceId={workspaceId}to refresh one eligible definition.POST /api/v1/workflows/{workflowId}/sessionsto create a session owned by the linked AcornOps user.POST /api/v1/workflow-sessions/{sessionId}/messageswith{ kind: "launch", clientRequestId? }for the first execution, then{ kind: "follow_up", content, clientRequestId? }for replies.
clientRequestId only when retrying the same provider message; use a new
value for a new user message. This makes transport retries idempotent without
making unrelated requests collide. Runtime inputs, targetId, and
targetType body fields are rejected. External credentials cannot list arbitrary Workflow
sessions or use another user’s session, and write access remains an explicit
three-layer opt-in.
Bot adapter pattern
An external integration adapter usually follows this flow:- Ask the linked AcornOps user with
manage_webhooksto create a webhook subscription for the events the bot needs. - Verify
AcornOps-Signatureusing the subscription secret. - Map the event to a channel, thread, incident, or user-visible card.
- For read-only context, link to the management console, use an authenticated user session, or call an explicitly documented linked-user route with the installed client credential and observed external user ID.
- For write approvals, render approve and reject controls only when the click can be tied back to a real AcornOps user.
- Submit approval decisions to
POST /api/v1/runs/{runId}/approvals/{approvalId}/decision.
workflowSessionId as the external thread
mapping. Each external message requires a new clientRequestId and creates a
new execution in that session. A reply after completion retains the conversation
history and stored Workflow snapshot, but it creates new run IDs and fresh
approvals. The current Workflow must remain active, and AcornOps recompiles the
session’s access from current effective permissions for every message.
Use GET /api/v1/workflow-executions/{executionId} for sanitized state and
GET /api/v1/workflow-executions/{executionId}/stream for aggregate,
replayable SSE. The execution stream discovers each next-step run and approval,
so adapters do not need to poll an unknown sequence of individual run streams.
Resume with Last-Event-ID or after. Any linked integration with effective
workspace read access may inspect safe execution metadata and events, including
executions started elsewhere. Session replies, approval decisions, and report
metadata/downloads remain restricted to the exact originating link and client.
Direct run reads follow the same disclosure boundary. Linked integrations see
a bounded run projection, and only the exact originating link/client receives
the final assistant output needed by its adapter. External run event lists,
per-run SSE, and nested aggregate run events keep lifecycle and safe approval
metadata while removing prompts, reasoning, token deltas, raw tool arguments,
and tool results.
Run approval lists and decision responses use the same boundary. Linked
integrations receive only bounded control metadata such as approval identity,
safe summary, state, target, and expiry. Executable arguments, tool references
and digests, actor identifiers, continuation state, and tool results remain
browser/internal-only.
Webhook events
Webhook events and delivery jobs are stored durably in Postgres and signed with HMAC-SHA256. Delivery is at least once: consumers must handle duplicate and out-of-order events. One stable event ID and immutable body are reused across all recipients and retry attempts. Delivery URLs must use HTTPS. AcornOps rejects embedded credentials, IP-literal URLs, redirects, localhost, metadata endpoints, and reserved destinations. A deployment can opt an exact DNS hostname or leading-wildcard hostname into private-address delivery, but this does not weaken the remaining URL and DNS checks. Workspace users withpermissions.manage_webhooks can create, edit, disable, delete, and inspect delivery history for outgoing webhooks from Workspace Settings. The create response returns the signing secret once. Store that secret in your integration and do not put it in a delivery URL.
Webhook subscriptions store concrete event types. The management console may offer event group shortcuts, but it expands those groups before saving the subscription.
Each delivery includes:
AcornOps-Event-IdAcornOps-Event-TypeAcornOps-TimestampAcornOps-Signature
targetId and targetType. Kubernetes events also include clusterId, which matches the Kubernetes target ID.
The signature input is timestamp + "." + raw_json_body, encoded as v1=<hex>.
Issue lifecycle events
Subscribe to these events for issue alerts:issue.created.v1when a new fingerprint becomes activeissue.reopened.v1when a resolved issue becomes active againissue.resolved.v1after the resolution grace period
subject.type: "issue" and includes a bounded issue
snapshot in data. Use lifecycleVersion to reject older state and stateAsOf
to distinguish the authoritative snapshot time from the later delivery time.
The payload excludes raw findings, observations, logs, search text, and latest
evidence.
Issue webhooks are current-action notifications, not a complete audit log.
When an issue enters recovery, AcornOps pauses pending created or reopened
notifications without consuming delivery attempts. Resolution or reopening
supersedes older pending lifecycle notifications. A receiver can therefore see
issue.resolved.v1 without first receiving issue.created.v1. Query the issue
API for authoritative current state.
Retry and subscription behavior
AcornOps retries transient network and DNS failures, timeouts, HTTP408,
425, 429, and 5xx responses. It honors a bounded Retry-After value or
uses jittered exponential backoff, and stops after 10 attempts or 24 hours.
Redirects, blocked destinations, configuration failures, and other
nonretryable 4xx responses are terminal.
The recipient set is captured when an event occurs. New subscriptions do not
receive historical events. Before each attempt, AcornOps rechecks whether the
subscription is enabled and still selects the event and target, then uses its
current canonical URL and signing secret. Delivery ordering is not global.
External webhook route connect/status
Some bot adapters create one delivery route per external user or destination, then ask the AcornOps user to subscribe workspace events to that route URL. After the user links the external account and creates the webhook subscriptions, the bot can claim live subscription metadata for that route. For the Mattermost bot, run!webhook create to obtain the user-level delivery URL. The same linked AcornOps user must add that exact URL to one or more subscriptions in Workspace Settings and then run !webhook connect. The connect call is the secret handoff for this route: it rotates each matching subscription secret and returns the new value once over authenticated TLS. Do not paste a signing secret into Mattermost or put it in the delivery URL.
Connect a route:
permissions.manage_webhooks. Each successful connect rotates the matching signing secrets and returns the fresh signingSecret values in that response. Treat reconnect as the documented secret recovery and rotation flow.
Check route status:
unconfigured, configured, or connected plus current workspace/event/enabled state. Status always reloads live AcornOps authorization and subscription state and never includes signing secrets. The Mattermost bot’s !webhook status command uses this route without exposing its locally retained secrets.
Write approval integrations should handle:
run.tool_approval_requested.v1run.tool_approval_decided.v1
mcp.server.created.v1mcp.server.updated.v1mcp.server.deleted.v1mcp.server.tested.v1
Tool and MCP integrations
There are two different integration directions:
Remote MCP servers can receive non-secret
publicHeaders. Credentials must use the secret-backed auth fields. Platform scope headers such as x-workspace-id, x-target-id, x-target-type, and x-run-id are reserved and added by the gateway.
See MCP and tools for MCP setup and header policy.
Start here
Use this sequence for a new integration:- Confirm the platform is deployed and reachable from your integration host.
- Decide whether the integration is webhook-driven, user-session driven, linked-external-user driven, or a combination.
- Create a workspace webhook subscription for the required event types.
- Verify signatures before acting on payloads.
- Use API overview to confirm API boundaries, then use the API reference sidebar for endpoint schemas.
- Use MCP and tools only when AcornOps should call tools exposed by another system.