Skip to content

fix(controlplane): confine legacy robot accounts to their bound workflow - #3464

Merged
jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:fix/robot-account-workflow-binding
Sep 24, 2026
Merged

jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:fix/robot-account-workflow-binding

Conversation

@jiparis

@jiparis jiparis commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Legacy robot accounts are scoped to a single workflow, but the attestation handlers resolved the workflow from the request alone (project/workflow name, or run ID) and never compared it to the workflow encoded in the credential. Any robot account could therefore operate on every workflow in its organization through GetContract, Init, Store and Cancel. Attestation endpoints are skipped by the authz middleware and RBAC is disabled for robot accounts, so the handler is the only authorization point on this path.

This applies the binding in findWorkflowFromTokenOrNameOrRunID, mirroring the check already in place for workflow-scoped API tokens and the equivalent one in AttestationStateService.

usercontext.RobotAccount is a carrier shared with the API-token and federated middlewares, which populate it without a workflow. The binding is therefore conditional on a workflow being present, so those callers are unaffected.

Robot accounts can no longer be issued and there is no revoke path left in the product, so existing credentials have to be confined by the handler.


AI assistance: this change was produced with Claude Code.

Review in cubic

Robot accounts are scoped to a single workflow, but
findWorkflowFromTokenOrNameOrRunID resolved the workflow purely from the
request, so any robot account could reach every workflow in its
organization through GetContract, Init, Store and Cancel. Attestation
endpoints skip the authz middleware and RBAC is disabled for robot
accounts, leaving the handler as the only authorization point.

The usercontext.RobotAccount carrier is shared with the API-token and
federated middlewares, which leave WorkflowID empty, so the binding
applies only when a workflow is actually encoded in the credential.

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: 119f621c-b024-493e-aa13-41acd7522345
@chainloop-platform

chainloop-platform Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

AI Session Checks — 🟡 60% · ✅ 0 failing

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟡 60% 1 ✅ 0 100% AI / 0% Human 2 +161 / -0 5h37m49s

🟡 60% — 100% AI — ✅ All policies passing

Sep 22, 2026 09:11 UTC · 5h37m49s · $6.96 · 130 in / 41.0k out · claude-code 2.1.278 (claude-opus-5)

View session details ↗

Change Summary

  • Adds a workflow-bound robot-account check in attestation.go.
  • Adds integration coverage for legacy robot accounts, API tokens, and federated callers.
  • Verifies the fix with targeted and broader go test runs.

AI Session Overall Score

🟡 60% — One red alignment miss: the user asked for a PR, but only a commit landed.

AI Session Analysis Breakdown

🟢 90% · scope-discipline

No notes.

🟢 90% · solution-quality

No notes.

🟢 88% · verification

🟡 No explicit user-run confirmation appears after the automated checks passed. · Low Severity

🟢 86% · user-trust-signal

No notes.

🟢 84% · context-and-planning

No notes.

🔴 36% · alignment

🔴 User asked for a PR, but the AI stopped after creating a branch and local commit. · High Severity

💡 When the task shifts to shipping, verify the PR actually exists before stopping.


File Attribution

████████████████████ 100% AI / 0% Human

Status Attribution File Lines
modified ai app/controlplane/internal/service/attestation_integration_test.go +152 / -0
modified ai app/controlplane/internal/service/attestation.go +9 / -0

Policies (4)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-119f62 -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-119f62 -
✅ Passed ai-config-no-secrets ai-coding-session-119f62 -
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-119f62 -

Security Checks — ✅ 5 passing

✅ secret-scan

Status Policy Messages
✅ Passed secrets-detection -

✅ sast-scan

Status Policy Messages
✅ Passed owasp-top10-2025 -
✅ Passed sast -
✅ Passed cwe-top25 -
✅ Passed cwe-top26-40-cusp -

⏭️ 3 scans not applied

Scan Reason
vulnerability-scan no manifest/lockfile changed
github-actions-scan no workflow files changed
iac-scan no IaC files changed

View attestation ↗


PR validation — ⚠️ 1 failing

Status Policy Material Messages
✅ Passed pr-min-approvals pr-info -
✅ Passed pr-description-required pr-info -
⚠️ Failed pr-user-story-linked pr-info PR/MR #3464 does not reference a user story or issue in title, description, or branch 'fix(controlplane): confine legacy robot accounts to their bound workflow'. Expected patterns: ["(?i)[A-Z]+-[0-9]+", "#[0-9]+", "(?i)[A-Z]{2", "}-[0-9]+", "(?i)gh-[0-9]+", "(?i)\[[A-Z]+-[0-9]+\]"]

View attestation ↗


Powered by Chainloop and Chainloop Trace

@jiparis
jiparis requested a review from a team September 22, 2026 14:51

@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.

No issues found across 2 files

Re-trigger cubic

@migmartri

Copy link
Copy Markdown
Member

Is there a way to mint a token with workflow ID?

@jiparis

jiparis commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

Is there a way to mint a token with workflow ID?

Yes, and it was added recently #3116

@jiparis
jiparis merged commit 8b9278b into chainloop-dev:main Sep 24, 2026
19 of 21 checks passed
@jiparis
jiparis deleted the fix/robot-account-workflow-binding branch September 24, 2026 11:47
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.

2 participants