Skip to content

CAS credentials: allow flagging system-token exchanges as SourceInternal to suppress transfer audit events #3198

Description

@migmartri

Context

#3189 made the Artifact CAS publish CASArtifactUploaded / CASArtifactDownloaded audit events, with a SourceInternal JWT claim that suppresses event publishing for the control plane's own traffic. Today that claim is only set by the controlplane's internal CASClientUseCase (app/controlplane/pkg/biz/casclient.go).

However, platform-side background processing obtains CAS tokens by exchanging an org-level system API token (biz.APIToken.IsSystem, created via APITokenAsSystem()) through CASCredentialsService/Get, which never sets SourceInternal. As a result, internal machine traffic — downloading attestation bundles during ingestion, fetching policy-evaluation bundles, SBOM processing, evidence evaluation, etc. — emits transfer events and is indistinguishable from genuine user uploads/downloads in downstream consumers.

Proposal

In CASCredentialsService/Get (app/controlplane/internal/service/cascredential.go), set SourceInternal: true on biz.CASCredsOpts when the authenticated caller is a system API token (currentAPIToken.IsSystem). This is not spoofable: system tokens are only minted by internal code paths and are hidden from the public API.

Scope decision

Two options:

  1. Blanket: flag every IsSystem token exchange. Simplest, no proto change. Caveat: sandbox trace tokens (per-workflow, also IsSystem) would be excluded too, so attestation/evidence uploads from sandboxed sessions would stop emitting events even though they store real bytes.
  2. Opt-in: add a source_internal field to CASCredentialsServiceGetRequest, honored only when the caller's token is IsSystem (ignored or rejected otherwise). Per-call control: callers flag only their internal read/processing paths while sandbox and storage-relevant uploads keep counting.

Option 2 is preferred if we want platform-generated uploads and sandbox traffic to remain visible in transfer accounting.

Out of scope

User-token and regular API-token exchanges must keep emitting events (CLI/UI uploads and downloads, AttestationService/GetUploadCreds, download redirects).

🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions