Public API style SENTRAL 008

Proposed API Design Sentral Openapi Tasks

Defines the versioned HTTP and OpenAPI-based public API contract for Dataverket operators, SDKs, and CLIs.

Author
Lars Solem
Updated

Status

Proposed on 2026-03-14 by Lars Solem.

Context

Dataverket needs a public control surface for operators, SDKs, and CLI tools. The platform plan already assumes one canonical API owned by Sentral, but the repository does not yet define whether that API is REST, gRPC, or some mix.

The platform also needs an interface that works well for:

  • human operators using CLI tools
  • SDK generation
  • long-running infrastructure operations
  • auditability and policy enforcement

Decision

Dataverket adopts a versioned HTTP API with OpenAPI as the public contract.

This API is the canonical external control surface for:

  • dv CLI family
  • generated SDKs
  • future web UI
  • operator and automation integrations

gRPC may be used internally between services where justified, but it is not the primary public API contract.

The public API is for platform consumers: operators, tenant administrators, SDKs, CLIs, and later tenant-facing automation. It is not a mirror of every internal service boundary.

API ownership model

Sentral owns the public API gateway and resource model.

Domain services such as Maskin, Plattform, Nett, Tjeneste, and Objekt may implement their own internal APIs, but public consumers interact through the Sentral-controlled API boundary.

This keeps:

  • authentication consistent
  • authorization centralized
  • audit and task models uniform
  • tenancy semantics consistent across products

Resource model

The API is resource-oriented.

Core resource categories include:

  • organizations or tenants
  • projects
  • environments
  • tasks
  • servers
  • virtual machines
  • clusters
  • networks
  • buckets
  • databases
  • applications

The public resource model should describe platform offerings and control-plane concepts, not expose every internal implementation service as a first-class public product.

Representative public categories therefore include:

  • control-plane resources such as tenants, projects, environments, tasks, audits, and placement policy
  • product resources such as virtual machines, clusters, networks, buckets, databases, and applications
  • operator-only inventory resources where operational control requires them

Internal implementation domains such as Sentral bounded contexts, NATS stream layout, or device-driver internals remain internal unless they need an explicit supported operator surface.

The public API should also support a coherent onboarding path for new tenants and projects. A tenant administrator should be able to discover prerequisites, create the initial project and environment structure, and create the first usable product resources without undocumented operator-only steps in the middle.

Endpoints should be organized around resources and lifecycle transitions rather than around RPC-shaped verbs.

Versioning model

The public API is explicitly versioned in the URL path.

The initial pattern is:

  • /v1/...

Breaking changes require a new major API version. Additive changes within a version are allowed when they preserve existing behavior.

API evolution policy

The platform must define API evolution rules early because Dataverket intends to support generated SDKs, long-lived automation, and CLI tooling on top of the same contract.

The baseline policy is:

  • additive, backward-compatible changes may be introduced within an existing major version
  • breaking changes require a new major version such as /v2/...
  • at least one previous major version should be supportable in parallel during migration unless there is an explicit exception ADR

This means versioning is not only a naming convention in the URL. It is a compatibility commitment.

Compatible changes within a major version

The following are normally acceptable within the same major version:

  • adding optional request fields
  • adding response fields that existing clients may ignore
  • adding new resource types or endpoints
  • adding new enum values only where clients are already expected to tolerate unknown values
  • adding pagination, filtering, or optional query features without changing prior behavior

These changes must preserve the meaning of existing fields and existing success and error behavior for unchanged requests.

Breaking changes

The following require a new major version unless a stronger compatibility argument is documented:

  • removing fields or endpoints
  • renaming fields
  • changing field meaning or validation semantics incompatibly
  • changing default behavior in a way that alters existing client-visible outcomes
  • changing error semantics in a way that breaks machine handling
  • narrowing accepted input in a way that invalidates previously valid requests

Parallel version support

When a new major version is introduced, Dataverket should support parallel operation of the old and new public API versions for a defined migration window.

That means:

  • /v1/... and /v2/... may coexist
  • OpenAPI documents must exist per supported major version
  • generated SDKs and CLIs must state which major version they target
  • migration guidance must exist before the older version is removed

The exact support window can be set later, but overlapping operation should be the default expectation for public API majors.

Deprecation and sunset posture

Deprecation should happen before removal.

The platform should provide:

  • explicit documentation that an endpoint, field, or behavior is deprecated
  • a replacement path where applicable
  • advance notice before removal of a supported major version or deprecated feature
  • a defined sunset policy for public API majors and generated SDKs

The exact notice period may be defined later, but the platform should not remove public API behavior silently.

Authentication and authorization

Authentication flows through Identitet using ZITADEL-backed OIDC tokens.

The public API must:

  • accept bearer tokens issued through the Dataverket auth flow
  • enforce tenant and project scoping
  • propagate actor identity into task records and NATS envelopes
  • expose consistent authorization failures

All CLIs continue to authenticate through dvid login.

Long-running operations

Infrastructure operations are frequently asynchronous. The public API therefore uses a task model for operations that are not expected to complete quickly.

The standard pattern is:

  1. Client submits a request.
  2. API validates and persists desired state.
  3. API returns a task resource.
  4. Back-end services execute asynchronously.
  5. Client polls task status or consumes task events.

This same task model should be used for onboarding workflows that require validation, approval, or multi-service orchestration.

Examples of async operations:

  • provision bare metal
  • create VM
  • create Kubernetes cluster
  • allocate network
  • rotate certificates

The v1 external client pattern is task polling through the public API.

Internal services may emit task lifecycle and domain events over NATS, but that internal event bus is not itself the public integration contract.

External event delivery such as webhooks or streaming APIs may be added later, but v1 should not assume them as required client behavior.

Error model

API errors must be structured and machine-readable.

At minimum, error responses should include:

  • stable error code
  • human-readable message
  • correlation ID
  • optional field-level validation details

The API must not force clients to scrape free-form text to determine what went wrong.

OpenAPI contract

OpenAPI is the canonical source for:

  • endpoint definitions
  • request and response schemas
  • auth requirements
  • generated SDKs
  • CLI request bindings where useful

The OpenAPI document must be version-controlled with the implementation.

Each supported major API version should have its own published OpenAPI contract so clients and SDK generators do not depend on undocumented compatibility assumptions.

SDK policy

SDKs should be generated where practical from the OpenAPI contract rather than handwritten first.

The first SDKs should target:

  • Go

Additional languages can follow when there is a real operator or customer need.

SDK versioning should track supported API majors explicitly. A generated SDK should make it clear which API major it targets, and SDK deprecation should align with the API version sunset policy.

CLI relationship

The dv CLI family is a thin, ergonomic layer over the public API.

CLI behavior should not invent capabilities that do not exist in the API. If a CLI flow needs special logic, that logic must still target supported API resources and operations.

CLI compatibility should also follow the public API evolution policy. CLI releases may add support for newer API majors, but they should not silently depend on unsupported breaking changes in an older API version.

Consequences

  • the platform gets one clear public contract instead of multiple competing entrypoints
  • SDK generation becomes straightforward
  • async infrastructure workflows are modeled consistently as tasks
  • HTTP ergonomics are prioritized for operator tooling
  • internal service teams remain free to use other protocols where they add value, without fragmenting the public surface
  • API versioning now carries an explicit compatibility and deprecation policy rather than only a path prefix convention

Decision Outcome

Proposed. This ADR records the current preferred direction and still needs acceptance before it becomes binding.

More Information

  • tenancy and resource hierarchy
  • task resource schema
  • API pagination, filtering, and sorting conventions
  • webhook or event-stream strategy for external consumers
  • API deprecation notice and sunset policy details

Audit

  • 2026-03-14: ADR proposed.