[18.9] Fix composite identity support for dependency proxy access
What does this MR do and why?
This backports three merge requests to 18-9-stable-ee:
!224207 (merged) was released in 18.10 and refactors the dependency proxy authentication in a way that makes it difficult to pick !228662 (merged) cleanly without it.
Duo bot service accounts (composite_identity_enforced: true) were denied access to the dependency proxy for two reasons:
-
GroupPolicy#dependency_proxy_access_allowedchecked the service account's own group membership. Service accounts are only added as project-level members, somax_member_access_for_userreturnedNO_ACCESSfor the group, causing the primary ability check to fail before the composite identity dual-check could run. -
Composite identity was not re-linked when the JWT was consumed. The dependency proxy uses a two-step flow: a short-lived JWT is issued at
/jwt/authand then used for the actual image pull. The JWT only carrieduser_id, so the scoped user context established during OAuth authentication was lost. WhenJwtAuthenticatablereconstructedcurrent_userfrom the JWT, no composite identity was linked in the request store, causingIdentity#valid?to returnfalse.
Fix
- Embed
scoped_user_idin the dependency proxy JWT when composite identity is linked at token-issuance time (ContainerProxyAuthenticationService). - Re-link the composite identity in
JwtAuthenticatablewhen the JWT is consumed, using the embeddedscoped_user_id. - Define
User#ai_service_account?asservice_account? && composite_identity_enforced?. All composite-identity-enforced service accounts are AI bots, so this is both accurate and free of fragile username-prefix heuristics. - Add an
ai_service_account_with_composite_identitycondition toGroupPolicyso AI service accounts with an active composite identity link pass the primary policy check. The scoped user's group membership is left entirely toAbility#with_composite_identity_check, keeping the policy free of redundant access-level lookups.
How the dual-check works
When Ability.allowed? is called for a user with composite_identity_enforced?, it runs the ability check twice: once for the current user (the AI service account) and once for the scoped user. Both must pass. The ai_service_account_with_composite_identity policy condition handles the service account side; Ability#with_composite_identity_check independently verifies Ability.allowed?(scoped_user, :read_dependency_proxy, group) for the scoped user side. Cross-group protection follows automatically — a linked identity from a different group will fail the scoped user's membership check.
References
Relates to #594535 (closed)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
- This MR is backporting a bug fix, documentation update, or spec fix, previously merged in the default branch.
- The MR that fixed the bug on the default branch has been deployed to GitLab.com (not applicable for documentation or spec changes).
- The MR title is descriptive (e.g. "Backport of 'title of default branch MR'"). This is important, since the title will be copied to the patch blog post.
- Required labels have been applied to this merge request
- severity label and bug subtype labels (if applicable)
- If this MR fixes a bug that affects customers, the customer label has been applied.
- This MR has been approved by a maintainer (only one approval is required).
- Ensure the
e2e:test-on-omnibus-eejob has succeeded, or if it has failed, investigate the failures. If you determine the failures are unrelated, you may proceed. If you need assistance investigating, reach out to a Software Engineer in Test in #s_developer_experience.
Note to the merge request author and maintainer
If you have questions about the patch release process, please:
- Refer to the patch release runbook for engineers and maintainers for guidance.
- Ask questions on the
#releasesSlack channel (internal only). - Once the backport has been merged, the commit changes will be automatically deployed to a release environment that can be used for manual validation. See after merging runbook for details.