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:
- 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.
- 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
Context
#3189 made the Artifact CAS publish
CASArtifactUploaded/CASArtifactDownloadedaudit events, with aSourceInternalJWT claim that suppresses event publishing for the control plane's own traffic. Today that claim is only set by the controlplane's internalCASClientUseCase(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 viaAPITokenAsSystem()) throughCASCredentialsService/Get, which never setsSourceInternal. 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), setSourceInternal: trueonbiz.CASCredsOptswhen 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:
IsSystemtoken exchange. Simplest, no proto change. Caveat: sandbox trace tokens (per-workflow, alsoIsSystem) would be excluded too, so attestation/evidence uploads from sandboxed sessions would stop emitting events even though they store real bytes.source_internalfield toCASCredentialsServiceGetRequest, honored only when the caller's token isIsSystem(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