Add GraphQL create mutation for the Anthropic Compliance credential
What does this MR do and why?
Part of https://gitlab.com/gitlab-org/gitlab/-/work_items/628487: the GraphQL mutation the Claude Compliance settings page needs to save a Compliance Access Key. Behind the claude_code_compliance_api_ingestion flag.
Includes the read field from !264354 (closed) until it merges; review only the create mutation commit.
- Mutation
anthropicComplianceIntegrationCreate(groupPath, apiKey): verifies and stores the key withSetAccessKeyService. ReturnserrorReason:INVALID_KEY,RATE_LIMITED,VERIFICATION_FAILED,BLANK_KEY,INVALID_INTEGRATION. Rate limited per group and per user, and records an audit event. - New permission
create_anthropic_compliance_integrationfor Owners, with granular token support.
Update (replace key, enable or disable) and delete mutations come in a follow-up MR.
Decisions to confirm
- Gated on
claude_code_compliance_api_ingestion, the same flag as the read field. - One permission per action (read, create; update and delete later) instead of a single ability.
- Rate limits: 10 attempts per hour per group and 10 per hour per user.
- No licence check, matching the rest of the feature.
- Create on a group that already has an integration returns
INVALID_INTEGRATION; replacing a key is the update mutation's job.
Database
Ai::Compliance::Anthropic::Integration.for_namespaces (used by the Group.anthropicComplianceIntegration batch loader). The batch holds one id per group loaded in the request.
SELECT "ai_compliance_anthropic_integrations".*
FROM "ai_compliance_anthropic_integrations"
WHERE "ai_compliance_anthropic_integrations"."namespace_id" IN (<namespace ids of the groups in the request>)Plan (Database Lab thin clone of gitlab-production-main, 20 ids): https://console.postgres.ai/gitlab/projects/gitlab-production-main/sessions/73058/commands/177054
Seq Scan on public.ai_compliance_anthropic_integrations (cost=0.05..0.05 rows=1 width=173) (actual time=0.007..0.008 rows=0 loops=1)
Filter: (namespace_id = ANY ('{...}'::bigint[]))
Time: 0.453 ms (planning 0.425 ms, execution 0.028 ms), 0 buffersThe table is empty in production today, so the planner picks a sequential scan. It holds at most one row per top-level group (index_ai_compliance_anthropic_integrations_on_namespace_id, unique), so as rows are added the lookup is served by that index.
How to set up and validate locally
bundle exec rspec ee/spec/requests/api/graphql/mutations/ai/compliance/anthropic ee/spec/policies/ee/group_policy_spec.rb -e create_anthropic_compliance_integrationIn GraphiQL, as a top-level group Owner with the flag on, run anthropicComplianceIntegrationCreate with any key. Without a real Compliance Access Key it returns errorReason: INVALID_KEY.
References
- Part of https://gitlab.com/gitlab-org/gitlab/-/work_items/628487
- Epic: https://gitlab.com/groups/gitlab-org/-/work_items/21540
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.