Skip to content

feat(server): bundle attestation for /v1/bundle (non-interactive signing) #1150

Description

@lockwobr

Problem

The /v1/bundle endpoint (aicrd) does not attest or sign bundles at all. The handler builds aicr.BundleOptions{Config, OutputDir, Timeout} with no Attester (pkg/server/bundle_handler.go), so server-generated bundles are always unsigned — there is no server-side equivalent of aicr bundle --attest. The OpenAPI spec reflects this, framing attestation as a CLI-only flow that "requires OIDC interactive or ambient authentication" (api/aicr/v1/server.yaml).

This blocks the server from participating in the enterprise signing use cases tracked by the rest of the epic: a CI pipeline or platform that bundles via the API cannot get a signed artifact back.

Why this is separate from the CLI signing work

The CLI's default signing path is interactive browser OIDC, which is a non-starter for a long-running daemon. So server-side attestation is not just "pass the existing attester through" — it needs a signing identity that works without a human at a browser:

  • KMS-backed signing (depends on feat(bundle): KMS-backed signing for CI/CD environments without OIDC #407) — the server signs with a configured KMS key (awskms:// / gcpkms:// / azurekms:// / hashivault://). This is the natural fit for a daemon and the most likely default.
  • Request-supplied / ambient OIDC — a pre-fetched identity token (e.g. workload identity) passed on the request, or ambient OIDC when aicrd itself runs in a CI context. Carries trust/expiry questions (the server signs on behalf of a caller) that need a design pass.

The client facade already has the seam: aicr.BundleOptions.Attester and MakeBundle honor an injected attester (pkg/client/v1/bundle.go). The missing piece is how the server constructs that attester and how the request/config expresses it.

Scope (proposed)

Dependencies

Out of scope

Success criteria

  • A bundle generated via POST /v1/bundle can be returned signed, using a non-interactive signing identity (KMS to start).
  • Private Fulcio/Rekor and tlog-upload behavior are configurable server-side where applicable.
  • OpenAPI and docs describe the server signing model and its trust boundary.
  • make test / make lint pass with no regressions.

Metadata

Metadata

Assignees

No one assigned

    Fields

    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions