Skip to content

API, worker, agent and Insight contracts

Abada 0.11 freezes the public REST surface under /api/v1 and external-worker protocol v1. Evolve them additively and prove compatibility from generated OpenAPI.

  • Keep persistence entities out of public schemas; map them to stable DTOs.
  • Existing paths, methods, field names, types and status meanings are stable.
  • New optional fields, endpoints, response headers and enum values are allowed.
  • List bodies remain JSON arrays. Pagination metadata uses X-Page, X-Page-Size, X-Total-Count and X-Total-Pages.
  • Mutation endpoints accept Idempotency-Key where deterministic replay is defined.
  • JSON errors use the stable ErrorResponse envelope and machine-readable ApiErrorCode values.

The generated OpenAPI document is checked against engine/src/test/resources/contracts/api-v1-contract.json by OpenApiContractTest.

sequenceDiagram
    participant W as Worker
    participant E as Engine
    participant DB as PostgreSQL

    W->>E: fetch-and-lock topics, maxTasks and duration
    E->>DB: atomically claim available tasks
    E-->>W: tasks, lease expiry, retries and trace context
    W->>E: heartbeat or extend-lock
    E->>DB: verify owner and active lease
    alt success
      W->>E: complete with workerId and variables
    else business outcome
      W->>E: BPMN error
    else technical failure
      W->>E: failure and retry policy
    end
    E->>DB: atomic transition and history

Completion, heartbeat, extension, failure and BPMN error validate worker ownership and lease expiry. Trace context propagates with acquired work. The Java SDK under sdk/java is the executable reference client.

The agent profile is additive to worker protocol v1. Locked tasks for native APL agent nodes carry an optional agentWork descriptor (profile, model, prompt inputs, result variable, schema, tools, confidence threshold, retry bounds); ordinary BPMN and engine-task workers receive null and stay compatible. Completion and failure bodies accept an additive agent attempt-metadata block — model, provider, attempt, latency, tools, promptHash, error type and confidence — persisted on the task row and in history. Workers that ignore unknown JSON fields remain protocol-v1 compatible; agent workers must reject a missing or unknown profileVersion.

Global (first-party) workers self-register once via PUT /v1/workers/me, poll fetch-and-lock without a projectId, and receive the owning projectId in each locked-task payload. Operator visibility comes from GET /v1/workers/me and the per-project worker-health surface.

Insight endpoints are additive to API v1 and follow the same compatibility policy. Reads (configuration, policies, proposals) require insight:read; review actions require insight:review; policy updates require insight:configure. Proposal lists are paginated; review requests carry expectedUpdatedAt (a stale request returns a typed 409) and policy updates carry expectedVersion. requiredApprovals must equal the number of distinct reviewer groups in the policy.

  1. Update the DTO and controller without leaking an entity.
  2. Preserve old input unless a versioned migration explicitly changes it.
  3. Add typed success, invalid-input and authorization tests.
  4. Update the OpenAPI compatibility manifest.
  5. Update Studio or the Java SDK if they consume the contract.
  6. Update the API or worker protocol reference in the same change.

Platform administration endpoints (/api/v1/admin/**)

Section titled “Platform administration endpoints (/api/v1/admin/**)”

The engine proxies the Keycloak Admin API under /api/v1/admin/**. These are additive to API v1 and do not change the worker protocol. They are governed by the same compatibility policy but with an extra rule:

  • The proxy is keyed off abada.identity.admin.* configuration. When those are absent, GET /api/v1/admin/status reports configured: false and every other admin endpoint returns 503 with an empty body. Engine startup is unaffected.

Endpoints, payload shapes and idempotency notes live in /docs/reference/api-v1.md.

The SecurityConfig restricts /api/v1/admin/** to users whose JWT carries the abada-admin authority (mapped from the abada-admin group via the JWT groups claim, or from the X-Auth-Request-Groups header in trusted-proxy mode). Negative tests for missing or wrong group are part of SecurityAuthorizationContractTest.

The Keycloak Admin API is service-account-only. The engine authenticates with a dedicated confidential client (abada-admin-api) whose service account holds the realm-management client roles manage-users, manage-groups, query-users, view-users, query-groups, view-groups, manage-realm and view-realm. These must be granted as clientRoles of the realm-management client — realm roles with those names do not authorize the Admin REST API and result in 403 responses. The same engine shares an audience validator across user JWTs and service-account JWTs, so the service account’s audience claim must equal OIDC_AUDIENCE (or abada-admin-api if the audience mapper is installed — see /docs/reference/security-and-rbac.md).