Skip to content

Conversation

balcsida
Copy link
Contributor

@balcsida balcsida commented Aug 26, 2025

Summary

  • Removed wildcard repository scopes (repository:*:*) that are incompatible with ABAC-enabled registries
  • Implemented repository-specific token scoping for all repository operations
  • Maintained catalog access with registry:catalog:* scope only

Changes

  • Modified initial authentication to only request registry:catalog:* scope
  • Updated token refresh to use repository-specific scopes (repository:<name>:*) for each operation
  • Added helper functions refreshTokenForRepository and refreshTokenForCatalog for cleaner scope management
  • Updated all repository operation methods to request appropriate scopes

Test Plan

  • Run existing unit tests (go test ./internal/api/...)
  • Run command tests (go test ./cmd/acr/...)
  • Build binary successfully (go build)
  • Manual testing with ABAC-enabled registry
  • Manual testing with regular (non-ABAC) registry
  • Verify acr purge command works with identity having full data plane permissions

Fixes #501

@balcsida balcsida force-pushed the fix/abac-registry-support branch from 2ed16de to 8b52681 Compare August 26, 2025 08:27
@balcsida balcsida changed the title Fix: Support ABAC-enabled registries (fixes #501) Fix: Support ABAC-enabled registries Aug 26, 2025
@balcsida balcsida force-pushed the fix/abac-registry-support branch from 8b52681 to 112ab91 Compare August 26, 2025 08:59
// This supports both ABAC and non-ABAC registries.
func refreshTokenForRepository(ctx context.Context, c *AcrCLIClient, repoName string) error {
// For specific repository operations, request full permissions on that repository
scope := fmt.Sprintf("repository:%s:*", repoName)
Copy link
Contributor

@estebanreyl estebanreyl Aug 26, 2025

Choose a reason for hiding this comment

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

I think in order to support ABAC we need to make sure that the tighter permissions are selected for the scope. The way to do this typically is to send a challenge message and get the actual permissions for each type of operation but that's a bit expensive here and probably amounts to a larger rework. I'll follow up with my teammates who are more familiar with the path.

Actually, I think I understand now that we just cant request all the scopes at once like before. In that case this lgtm but I'll still double check and run a test on it

Copy link
Contributor Author

@balcsida balcsida Aug 26, 2025

Choose a reason for hiding this comment

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

Sorry, I (again) forgot to push some commits and didn't open the PR as draft. I'm still finishing up the test-abac-registry.sh

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Additionally, I'm thinking about using testscript instead of using bash scripts for these... functional test? I don't really know the correct terminology here

Copy link
Member

Choose a reason for hiding this comment

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

"repository:%s:*" does not work for ABAC-enabled registries either. For ABAC registries, the request must include the specific scope, such as repository:%s:pull,push.

@balcsida balcsida force-pushed the fix/abac-registry-support branch from 8f77998 to 49686b0 Compare August 26, 2025 19:16
accessTokenResponse, err := newAcrCLIClient.AutorestClient.GetAcrAccessToken(ctx, loginURL, "registry:catalog:* repository:*:*", refreshToken)
// For ABAC-enabled registries, only request catalog scope initially
// Repository-specific scopes will be requested when needed
accessTokenResponse, err := newAcrCLIClient.AutorestClient.GetAcrAccessToken(ctx, loginURL, "registry:catalog:*", refreshToken)
Copy link
Member

Choose a reason for hiding this comment

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

We can't simply remove the repository scope check from newAcrCLIClientWithBearerAuth. The new refreshTokenForRepository method is only invoked when the existing token has expired. Other files still call this method to obtain the CLI client with the token (example)

balcsida added a commit to balcsida/acr-cli that referenced this pull request Aug 26, 2025
…and use specific ABAC permissions

- Try repository:*:pull scope first for non-ABAC registries to maintain backward compatibility
- Fallback to catalog-only scope for ABAC registries
- Use specific permissions (pull,push,delete) instead of wildcard for ABAC repository operations
- Addresses lizMSFT review comments on PR Azure#504
…and use specific ABAC permissions

- Try repository:*:pull scope first for non-ABAC registries to maintain backward compatibility
- Fallback to catalog-only scope for ABAC registries
- Use specific permissions (pull,push,delete) instead of wildcard for ABAC repository operations
@balcsida balcsida force-pushed the fix/abac-registry-support branch from 9be8375 to e2ff253 Compare August 26, 2025 19:39
@balcsida balcsida force-pushed the fix/abac-registry-support branch from 5331b0a to b88473d Compare September 16, 2025 23:01
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.

acr purge command: support ABAC-enabled registries if identity has full data plane permissions

3 participants