Privileged RDAP grant administration (RPD §9)#2941
Merged
OlegPhenomenon merged 2 commits intoJul 13, 2026
Conversation
Admin CRUD, inside the registry app, for managing RdapPrivilegeGrant (spec 09-registry-privileged-admin), sitting next to the data it manages. - Migration: add full_name (NOT NULL), legal_basis_ref (NOT NULL) and optional personal_id_code to rdap_privilege_grants; new per-model log_rdap_privilege_grants audit table + creator_str/updator_str columns. - Model: include the Versions concern (immutable paper_trail audit), presence validations for full_name/legal_basis_ref, and a read-time derived expired?/display_status (STATUSES stays active/revoked/suspended). - Controller/views/routes: top-level admin CRUD mirroring admin_users, with distinct suspend/revoke member actions and no destroy (grants end via suspend/revoke only; audit entries have no edit/delete route). - Ability: can :manage, RdapPrivilegeGrant for the admin role only. - personal_id_code is capture-only: never in the index, never in the frozen internal grants serializer, filtered from logs (config.filter_parameters). - The frozen api/v1/internal/rdap/grants_controller#serialize is untouched; active_for_subject and grant_id are unchanged. - Fresh i18n keys + menu link; all 6 fixtures populated for the new columns. - Tests: model (validations, derived expired, revoke-takes-effect), admin integration (CRUD, suspend/revoke, auth gating, audit history, no-delete route, no PII/no missing-translation), serializer no-leak.
…it history
Closes the AC23 gap the tester found: the show page's paper_trail audit
table is built from object_changes, a potential PII vector. The view already
does object_changes.except('personal_id_code'); this test proves it — creates
a grant with the code, makes an audit-generating change, asserts the value
never appears on the rendered show page.
43 runs / 140 assertions / 0 failures via docker exec docker-images-registry-1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Admin CRUD for
RdapPrivilegeGrant, built inside the registry app next to the data it manages (spec09-registry-privileged-admin; RDAP specs-repo companion PR internetee/RDAP#feat/09-registry-privileged-admin). Stacks onfeat/rdap-data-api(PR #2937).What this adds
full_name(NOT NULL),legal_basis_ref(NOT NULL), optionalpersonal_id_codeonrdap_privilege_grants; new per-modellog_rdap_privilege_grantspaper_trail table +creator_str/updator_str.include Versions(immutable audit), presence validations, read-time derivedexpired?/display_status. StoredSTATUSESstaysactive/revoked/suspended.admin_users, with distinctsuspend/revokemember actions and nodestroy.can :manage, RdapPrivilegeGrantfor theadminrole only. Gated menu link + fresh i18n.personal_id_codeis capture-only — absent from the index and the frozen internal serializer, filtered from logs (config.filter_parameters), omitted from the rendered audit-change table.Frozen contract preserved
api/v1/internal/rdap/grants_controller#serializeis byte-for-byte unchanged (git diff empty);active_for_subjectandgrant_iduntouched. A serializer test asserts the new admin-only fields never leak.Tests (Docker shared stack)
docker exec docker-images-registry-1 bin/rails teston the affected files: 42 runs / 135 assertions / 0 failures / 0 errors — model, admin integration (CRUD, suspend/revoke, auth gating, audit history, no-delete route, no PII, no missing translations), and serializer no-leak. Audit test proves alog_rdap_privilege_grantsrow is written on create and update withwhodunnit = id_role_username.Notes for reviewers
eeid_subject, but the model requires it and creating a valid grant is impossible without it — so it is permitted and on the form.personal_id_codeencryption-at-rest is deferred to a follow-up (Rails 6.1 has noActiveRecord::Encryption, no in-app precedent); recorded, not dropped.Do not merge without review.