Context
#3408 caps the policy-evaluations bundle the WorkflowRunService.View API is willing to download and inline. To learn the bundle size before paying for the transfer, the control plane calls CASClient.Describe against the org's CAS backend, and falls back to a REASON_UNAVAILABLE reference when the size cannot be determined.
This adds a CAS round trip (temporary credentials, gRPC connection, backend HEAD) on every View of an attestation that carries a policyEvaluationsRef, even when the bundle is small and would be inlined anyway. It also makes the decision depend on the backend reporting a content length, which some backends omit, in which case we refuse to inline a bundle that may be tiny.
Proposal
Record the bundle size in the attestation itself and use that instead of calling the CAS.
The CLI already builds the policyEvaluationsRef as an in-toto ResourceDescriptor in uploadPolicyEvaluationsBundle (app/cli/pkg/action/attestation_push.go). Today it only sets name, digest and mediaType. It has the marshalled bundle bytes in hand, so it can add the size, for example as chainloop.dev/size under annotations (or a dedicated field if we prefer). The descriptor is part of the signed statement, so the value is tamper-proof.
On the server side, resolvePolicyEvaluations (app/controlplane/internal/service/workflowrun.go) would then:
- Read the size from the descriptor. If it is above the cap, return
REASON_TOO_LARGE without touching the CAS.
- If it is under the cap, download straight away, keeping the existing
boundedBuffer so an inconsistent descriptor cannot push us past the cap.
- Only when the attestation predates the annotation (no size present) fall back to the current
Describe call.
This removes the extra round trip from the hot path, works regardless of whether the backend reports a content length, and the result does not depend on CAS availability for the "too large" decision.
Notes
- Existing attestations do not carry the annotation, so the
Describe fallback needs to stay until we are comfortable dropping support for them.
Describe on biz.CASClient / casclient.Downloader can be kept for the fallback, or removed later together with it.
- Related: the cap does not apply to orgs on the inline CAS backend, since the CLI skips the bundle upload there and the evaluations stay embedded in the predicate. That is a separate problem from this one.
🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri
Context
#3408 caps the policy-evaluations bundle the
WorkflowRunService.ViewAPI is willing to download and inline. To learn the bundle size before paying for the transfer, the control plane callsCASClient.Describeagainst the org's CAS backend, and falls back to aREASON_UNAVAILABLEreference when the size cannot be determined.This adds a CAS round trip (temporary credentials, gRPC connection, backend
HEAD) on everyViewof an attestation that carries apolicyEvaluationsRef, even when the bundle is small and would be inlined anyway. It also makes the decision depend on the backend reporting a content length, which some backends omit, in which case we refuse to inline a bundle that may be tiny.Proposal
Record the bundle size in the attestation itself and use that instead of calling the CAS.
The CLI already builds the
policyEvaluationsRefas an in-totoResourceDescriptorinuploadPolicyEvaluationsBundle(app/cli/pkg/action/attestation_push.go). Today it only setsname,digestandmediaType. It has the marshalled bundle bytes in hand, so it can add the size, for example aschainloop.dev/sizeunderannotations(or a dedicated field if we prefer). The descriptor is part of the signed statement, so the value is tamper-proof.On the server side,
resolvePolicyEvaluations(app/controlplane/internal/service/workflowrun.go) would then:REASON_TOO_LARGEwithout touching the CAS.boundedBufferso an inconsistent descriptor cannot push us past the cap.Describecall.This removes the extra round trip from the hot path, works regardless of whether the backend reports a content length, and the result does not depend on CAS availability for the "too large" decision.
Notes
Describefallback needs to stay until we are comfortable dropping support for them.Describeonbiz.CASClient/casclient.Downloadercan be kept for the fallback, or removed later together with it.🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri