Add logging for read_virtual_registry access through project membership

What does this MR do and why?

This MR implements Phase 1 of the virtual registry access control fix by adding logging for users who access virtual registries through project membership (rather than direct group membership).

References

Screenshots or screen recordings

N/A

How to set up and validate locally

  1. To see the logs, we need to tail into the logs file:
# inside gdk/gitlab directory
tail -f log/application_json.log | grep "User granted"
  1. From rails console:
# select or create a public group
public_group = Group.all.detect(&:public?) || FactoryBot.create(:group, :public)

# create a non-memeber user
non_group_member = FactoryBot.create(:user)

# select or create a project in the group
project = public_group.projects.first || FactoryBot.create(:project, namespace: public_group)

# add the user as a project's member
project.add_guest(non_group_member)

# create a PAT for non_group_member to use in testing APIs
pat = FactoryBot.create(:personal_access_token, user: non_group_member, scopes: ["api","read_api"]) 

# fetch the token
pat.token
  1. Test with any rest API or graphql query that requires a read_virtual_registry permission:
curl  -H "PRIVATE-TOKEN: <non_group_member PAT>" http://gdk.test:3000/api/v4/groups/<public_group.id>/-/virtual_registries/packages/maven/registries | jq
  1. You should see a log for the access:
{"severity":"INFO","time":"2025-12-09T14:02:20.882Z","correlation_id":"f3a947a9b3cb673ee5de7beb549aabf6","message":"User granted read_virtual_registry access through project membership","user_id":83,"group_id":24}
  1. Test sending the same request with the admin PAT, nothing should be logged.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #581131

Edited by Moaz Khalifa

Merge request reports

Loading