Skip to content

Refactor: unify permission lists via all_permissions! callback macro #16

@bordumb

Description

@bordumb

Problem

The set of permission types is enumerated in multiple places that must stay in sync:

  1. capsec-core/src/permission.rs — struct definitions + Permission impls
  2. capsec-core/src/permission.rssealed::Sealed impls
  3. capsec-core/src/has.rsimpl_ambient! invocation
  4. capsec-core/src/has.rsimpl_tuple_has_first! / impl_tuple_has_second! invocations
  5. capsec-macro/src/lib.rsKNOWN_PERMISSIONS string array

Adding a new permission type requires updating all 5 locations. Missing one causes silent breakage (e.g., Cap<Ambient> loses coverage for the new type, or #[capsec::context] rejects it as unknown).

A compile-time exhaustiveness test was added to catch impl_ambient! omissions, but the root cause — multiple independent lists — remains.

Proposed fix

A small callback macro that defines the canonical list once:

macro_rules! all_permissions {
    ($macro:ident) => {
        $macro!(FsRead, FsWrite, FsAll, NetConnect, NetBind, NetAll, EnvRead, EnvWrite, Spawn);
    };
}

Each consumer invokes its own macro with the shared list:

all_permissions!(impl_sealed);
all_permissions!(impl_permission);
all_permissions!(impl_ambient);
all_permissions!(impl_tuple_has_first);
// etc.

Subsumption (FsAll => FsRead, FsWrite) stays hand-written — it's inherently non-uniform and shouldn't be auto-generated.

KNOWN_PERMISSIONS in capsec-macro can't use the Rust macro directly (proc-macro crate boundary), but could be generated by a build script or kept as a separate list with a compile-time test ensuring parity.

Scope

  • One source of truth for the permission enumeration
  • Each consumer site remains a separate, readable, auditable macro
  • No behavior change — pure refactor
  • Touches capsec-core/src/permission.rs, capsec-core/src/has.rs

Priority

v0.2 cleanup. The compile-time test in has.rs covers the immediate risk for v0.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions