Skip to content

Generic capability system for restricted features #28

Closed

Description

@NinjaLikesCheez

Context

Some features should be available to specific people, not to everyone who is a member, and not based on a Discord role. The example is a future door lock (#29). So Pixel needs a way to grant a named permission, a capability, to individual people, changeable by admin commands.

Depends on #24 (admin framework) and #25 (the store, which holds each person's capabilities).

Decided: build the generic system now, with no specific capabilities yet.

Goal

A command can require a capability, admins can grant and revoke capabilities per person, and the dispatcher enforces it centrally.

Scope

  • A capability registry in code: a name and a description for each capability. Admins can only grant names that exist, so typos can't create a silent grant. It starts empty.
  • Commands can require a capability on top of a minimum tier, for example access: { minTier: "member", capability: "door" }. Both must hold, so access can't outlive membership.
  • Enforced only in the dispatcher, like every other access check. Denied callers never reach the handler, and the denial is logged. The refusal is generic.
  • Not implied by anything else: not by a tier, not by a Discord role, and not by being an admin. An admin can grant themselves a capability, and that's audited like any other grant.
  • Hidden from /help for people who don't have it. (Discord still lists every registered command in its picker, and a bot can't change that per person, so "secret" means unauthorised people are refused, not that the command is invisible.)
  • /admin capability grant|revoke user: capability: with choices from the registry, plus /admin capability list [user]. All of them are audited via the store (Writable access store: members, friends and capabilities managed by admin commands #25).
  • Startup check: a command that requires an unknown capability stops startup.
  • Removing someone's tier removes their capabilities (Admin commands: /admin member set and /admin whois #26).

Acceptance criteria

  • A command requiring a capability is refused for a member without it, and allowed for one with it. Tier and capability must both hold (tested with a fake capability)
  • Granting persists across a restart and is audited with actor, target and capability. Revoking does the same
  • A guest, a friend below the required tier, and an admin without the grant are all refused
  • Only registry names can be granted, and an unknown name in a command stops startup
  • /help and the command list don't advertise it to people who lack it
  • Downgrading or removing someone makes their capability useless immediately
  • docs/identity-and-access.md is updated, including the threat model: a compromised Discord can't grant a capability
  • No real capabilities ship in this issue

Considerations

  • Per-resource capabilities (such as one door out of several) can come later, for example by naming (door:front)
  • Sensitive grants could ask for a confirmation step later

Decisions made

  • Commands are /admin capabilities grant, revoke and list (a subcommand group, so the framework now supports one level of subgroup).
  • A guest never passes a capability check, even if the file lists capabilities for them, and capabilities are not removed on demotion: they stay but are inactive.
  • Admins are members too: admins.yaml is a list of IDs and each admin needs a members.yaml entry. An admin can grant themselves a capability (audited), but nothing implies one.
  • Capability names in the file that no longer exist are ignored, logged and reported to Sentry.
  • With nothing registered, grant and revoke reply "No capabilities are registered yet."

Implemented in #34. Breaking change: the admins file format (see the PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecurityAuth, access control, privacy, secrets — needs human review

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions