Skip to content

feat: org setting to block attestations on released versions#3175

Merged
migmartri merged 4 commits into
chainloop-dev:mainfrom
migmartri:feat/block-attestations-on-released-versions
Jun 9, 2026
Merged

feat: org setting to block attestations on released versions#3175
migmartri merged 4 commits into
chainloop-dev:mainfrom
migmartri:feat/block-attestations-on-released-versions

Conversation

@migmartri

@migmartri migmartri commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

Adds an opt-in organization-level setting, block_attestations_on_released_versions, that prevents new attestations from being pushed to project versions that are already released (prerelease == false). The default is false, so existing behavior is unchanged.

When enabled, attempting to attest against a released version fails hard with a dedicated typed error mapped to a FailedPrecondition gRPC code, so the CLI can render a clear, actionable message.

chainloop att init --workflow build-container-image --project myproject3  --replace --version 1.1
ERR version "1.1" is released and immutable: attestations cannot be added

Enforcement

The guard is applied at two points:

  • Attestation init — enforced transactionally with a row lock while the project version is resolved, giving fail-fast feedback before any crafting work happens.
  • Attestation push (SaveAttestation) — the authoritative gate that closes the window where a version could be released concurrently between init and push.

Exposure

The setting is exposed through the organization settings API and the chainloop organization update --block-attestations-on-released-versions CLI command.

Closes #3174

AI assistance disclosure

This contribution was assisted by Claude Code.

Add an opt-in organization-level setting,
block_attestations_on_released_versions, that rejects new attestations
targeting project versions that are already released (prerelease == false).
Default is false, preserving current behavior.

Enforcement happens at two points: at attestation init, transactionally
with a row lock when resolving the project version, providing fail-fast
feedback before any work is done; and at push in SaveAttestation, which
acts as the authoritative gate closing the window where a version could be
released between init and push. Both return a dedicated typed error mapped
to a FailedPrecondition gRPC code so the CLI surfaces a clear message.

The setting is exposed through the organization settings API and the
chainloop organization update CLI command.

Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: 146f4ecb-bdc9-4562-8b1b-2481ea10d7bf
@chainloop-platform

chainloop-platform Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

AI Session Analysis

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟢 85% 1 ⚠️ 1 89% AI / 11% Human 20 +269 / -40 27m1s

🟢 85% — 89% AI — ⚠️ 1 policies failing

Jun 8, 2026 20:58 UTC · 27m1s · $36.10 · 94.4k in / 202.4k out · claude-code 2.1.168 (claude-opus-4-8)

View session details ↗

Change Summary

  • Adds an org setting that blocks attestations to released project versions.
  • Enforces the setting at attestation init and push, including the release-race path.
  • Exposes the toggle through control plane API, CLI org update flow, and generated docs/schema artifacts.
  • Adds focused integration coverage and reruns related workflow-run tests, builds, and lint checks.

AI Session Overall Score

🟢 85% — Verified feature work, with only planning discipline lagging the task breadth.

AI Session Analysis Breakdown

🟢 91% · solution-quality

🟢 AI added fail-fast and authoritative gates to cover the race window. · High Impact

🟢 89% · user-trust-signal

No notes.

🟢 88% · alignment

🟢 AI anchored implementation on the linked issue before editing. · High Impact

🟢 87% · scope-discipline

No notes.

🟢 84% · verification

🟢 Focused immutability tests passed, then related regressions passed too. · High Impact

🟡 No post-run user confirmation appeared; validation is entirely AI-driven. · Low Severity

🟡 72% · context-and-planning

🟠 Multi-layer work began after exploration, but no shared plan, TODO, or plan-mode step ever appeared. · Medium Severity

💡 For multi-file changes, write a short step list before editing so design choices and order stay reviewable.


File Attribution

█████████████████░░░ 89% AI / 11% Human

Status Attribution File Lines
modified ai app/controlplane/pkg/biz/workflowrun_integration_test.go +115 / -0
modified ai app/controlplane/pkg/biz/workflowrun.go +51 / -0
modified ai app/cli/pkg/action/membership_list.go +16 / -14
modified ai app/controlplane/pkg/data/workflowrun.go +18 / -8
modified ai app/controlplane/pkg/biz/errors.go +21 / -1
modified ai app/cli/cmd/organization_update.go +13 / -7
modified human app/cli/documentation/cli-reference.mdx +9 / -8
modified ai app/controlplane/internal/service/service.go +3 / -1
modified ai app/cli/pkg/action/org_update.go +3 / -0
modified ai app/controlplane/api/controlplane/v1/organization.proto +3 / -0
modified ai app/controlplane/pkg/biz/organization.go +3 / -0
modified human app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum +2 / -1
modified ai app/controlplane/api/controlplane/v1/response_messages.proto +2 / -0
created human app/controlplane/pkg/data/ent/migrate/migrations/20260608210839.sql +2 / -0
modified ai app/controlplane/pkg/data/ent/schema/organization.go +2 / -0
modified ai app/controlplane/pkg/data/organization.go +2 / -0
modified ai app/controlplane/internal/service/attestation.go +1 / -0
modified ai app/controlplane/internal/service/context.go +1 / -0
modified ai app/controlplane/internal/service/organization.go +1 / -0
modified human app/controlplane/pkg/data/ent/migrate/schema.go +1 / -0

Policies (4, 1 failing)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-146f4e -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-146f4e -
⚠️ Failed ai-config-no-secrets ai-coding-session-146f4e Potential secret (Quoted API key/password) found in session content [turn=130, source=tool_result, line=58, value=PASSWORD...ase"]
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-146f4e -

Powered by Chainloop and Chainloop Trace

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread app/controlplane/pkg/biz/workflowrun.go Outdated
@migmartri migmartri requested a review from a team June 8, 2026 21:30
migmartri added 3 commits June 8, 2026 23:34
Surface the org-level setting in `chainloop organization describe` so
admins can confirm whether the guard is enabled. Rendered only when on,
matching the existing selective output style.

Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: 146f4ecb-bdc9-4562-8b1b-2481ea10d7bf
Add codes.FailedPrecondition to the set of gRPC codes whose server message
is surfaced verbatim, stripping the wrapped chain prefix. This makes the
released-version immutability error read as a clear, actionable message on
both attestation init and push.

Also align the organization describe output to use a colon separator for
the policy strategy line, consistent with the other settings rows.

Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: 146f4ecb-bdc9-4562-8b1b-2481ea10d7bf
The push-side guard previously read the project version's release status and
then persisted the attestation in separate operations, leaving a TOCTOU
window where a concurrent release could be bypassed (identified by cubic).

Move the prerelease check into the persistence transaction and lock the
project version row (FOR UPDATE) so the check and the attestation write are
atomic and serialized against a concurrent release. The organization setting
is resolved up front and threaded into the repo persistence methods, matching
how the init path already passes the flag down.

Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: 146f4ecb-bdc9-4562-8b1b-2481ea10d7bf
@migmartri migmartri merged commit b53424d into chainloop-dev:main Jun 9, 2026
15 of 16 checks passed
@migmartri migmartri deleted the feat/block-attestations-on-released-versions branch June 9, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add org setting to make released project versions immutable (block attestations to released versions)

2 participants