Permissions¶
The DNS module ships six site-wide permissions (one global, five zone-flavored) plus a separate per-zone delegation system that lives on each zone's "Collaborators" tab. The two layers are deliberately distinct:
- Site-wide permissions appear at
/admin/people/permissionsand apply across every zone on the site. They're per-role. - Per-zone capabilities (described in
Per-zone delegation below)
are stored as
dns_zone_grantentity rows and apply only to the one zone each row references. They never appear on the site permissions page and are never assignable to roles. There are seven of them (view zone,edit zone,delete zone, plus four record-flavored caps); the delegation section lists them in full.
The access handler resolves any operation in this order:
administer dns— super-admin escape (allow).- Per-zone calculated permissions — emitted by the
DnsZoneGrantPolicyaccess policy in thedns_zonescope. Owners of a zone are implicitly granted all seven capabilities; explicit grant rows extend this to other users. - Site-wide permission fall-through —
view any dns zoneand the*own dns zonespermissions cover the legacy multi-tenant case for installs that haven't set up per-zone grants.
Records have no dedicated permissions in 2.x — record access is
fully derived from the parent zone's access (whether through site-wide
permissions or a per-zone grant).
Global¶
| Permission | Effect |
|---|---|
administer dns |
Full administrative access plus the gate for the admin overview pages (/admin/content/dns/...). |
administer dns is restrict access: true — granting it implies the
ability to read or modify any zone or any record, regardless of
ownership. It also opens the admin landing and the Views-backed
zones / records collection pages.
Users without administer dns can still create, view, and edit their
own zones (subject to the per-zone permissions below) by visiting
zone URLs directly (/dns/{zone}). They don't get the admin overview
pages.
Zones¶
| Permission | Effect |
|---|---|
create dns zones |
Add new zones via /dns/zones/add. |
view any dns zone |
Read every zone, regardless of owner. |
view own dns zones |
Read zones whose uid matches the current user. |
edit own dns zones |
Edit zones whose uid matches the current user. |
delete own dns zones |
Delete zones whose uid matches the current user. |
There is no edit any dns zone or delete any dns zone —
cross-user editing is handled by either administer dns or by an
explicit per-zone grant (see Per-zone delegation).
Records¶
Records have no dedicated site-wide permissions. Each record op
maps to a record-flavored capability on the parent zone, and the
access handler resolves through the same chain documented in the
lead: administer dns → per-zone calculated
permissions → site-wide fall-through. The op-to-capability mapping:
| Record op | Capability checked on the parent zone |
|---|---|
| View | view records |
| Create | create records |
| Update | edit records |
| Delete | delete records |
So a collaborator granted only edit records on a zone can update
existing records but cannot create or delete them; a collaborator
granted only view records is read-only; the zone owner gets all
four implicitly. Site-wide fall-through covers the legacy case:
view ops still defer to the parent zone's view access, so
view any dns zone continues to surface records in admin views
without per-zone grants.
This means: own a zone, manage its records.
Suggested role configurations¶
Single-tenant site (one team manages all DNS): give the editor
role administer dns. Done.
Multi-tenant (each user manages their own zones): grant
create dns zones, view own dns zones, edit own dns zones,
delete own dns zones. Users access their zones via direct URL or
via links surfaced by other site features (a custom dashboard view,
e.g.). The admin overview pages stay administrator-only.
Read-only auditor: grant administer dns (the only way to access
the admin overview today) plus rely on the audit-trail / log story.
A read-only auditor permission set is on the roadmap.
Per-zone delegation (collaborators)¶
Beyond the site-wide permissions above, each zone has a Collaborators tab on its canonical page where the zone owner (or an administrator) can grant another Drupal user a specific capability set on that one zone. This is how multi-user teams share a zone without making everyone the owner.
A collaborator's grant is strictly local to its zone — it never
becomes a Drupal site-wide permission, never applies to other zones,
and never appears on /admin/people/permissions. Adding or
modifying grants is itself restricted to the owner (and admins)
specifically to prevent privilege escalation: a collaborator with
edit zone capability deliberately cannot add new grants.
The capability vocabulary on a grant:
| Capability | What it gates |
|---|---|
view zone |
See the zone exists and read its metadata |
edit zone |
Change zone label, TTL defaults, etc. |
delete zone |
Delete the zone (still gated on no-records-exist) |
view records |
List and read records in the zone |
create records |
Add new records |
edit records |
Change existing records |
delete records |
Remove records |
Common roles:
- Records admin →
view zone, view records, create records, edit records, delete records - Records editor →
view zone, view records, edit records - Read-only viewer →
view zone, view records
The zone owner is automatically granted all seven capabilities
on their own zone — no grant row required. Adding a grant for the
owner is rejected by the form as redundant. Admins
(administer dns) bypass the system entirely.
Resolution chain when the access handler decides whether a user can perform an op on a zone (or one of its records):
1. administer dns → ALLOW (super-admin escape)
2. dns_zone-scope calculated perms → ALLOW if the matching capability
is in the grant for this user
on this zone
3. legacy site-wide perms → ALLOW per the site-wide perms
table above (for installs that
haven't moved to grants)
Provider integrations (e.g. a future dns_cloudflare module) can
register an additional access policy in the same dns_zone scope
to enforce constraints — for example, declaring all capabilities
revoked on zones imported read-only from the provider. See the
architecture page for how this
extension point will be used.