Skip to content

feat(sea): add SEA.role - signed RBAC role tokens - #1426

Open
ABsUP wants to merge 1 commit into
amark:masterfrom
OpenCodeWEB:feat/sea-role
Open

ABsUP wants to merge 1 commit into
amark:masterfrom
OpenCodeWEB:feat/sea-role

Conversation

@ABsUP

@ABsUP ABsUP commented Aug 15, 2026

Copy link
Copy Markdown

feat(sea): add SEA.role — signed RBAC role tokens

Adds a minimal, self-contained RBAC primitive: administrators issue signed role tokens that can be verified anywhere, stored in a roles node, or handed directly to users.

API

// Admin issues a role to Bob:
const token = await SEA.role.grant(admin, bob.pub, 'editor', null, { expiry: Date.now() + 30*86400000 });

// Anyone holding admin's public key can verify:
const payload = await SEA.role.verify(token, admin.pub); // { u, r, iat, exp } or undefined

// Boolean convenience check:
const ok = await SEA.role.has(token, 'editor', bob.pub, admin.pub); // true

Properties

  • Signed by admin: the token is a SEA.sign envelope over { u: userPub, r: role, iat: now, exp: expiry } — unforgeable without the admin's private key.
  • Verifiable anywhere: only the admin's public key is needed to check — ideal for distributed graphs, relays, and serverless edge functions.
  • Expiry: opt.expiry gives an absolute expiry timestamp (checked on verify); 0/omitted means the token never expires. opt.now allows clock-independent tests.
  • Roles node pattern: store tokens at ~adminPub/roles/{role} (a "roles node") for on-graph role discovery; verify before authorizing writes.
  • Composes with SEA.certify: grant write policies to users whose role tokens you've verified.
  • Tamper-evident: any modification of the token fails signature verification → undefined.
  • Supports both promise and callback styles.

Example (roles node)

// grant
const token = await SEA.role.grant(admin, bob.pub, 'editor');
gun.get('~' + admin.pub).get('roles').get('editor').set(token);

// authorize (e.g. in a serverless edge function)
const tokens = await gun.get('~' + admin.pub).get('roles').get('editor').once();
const allowed = await SEA.role.has(tokens, 'editor', bob.pub, admin.pub);

Tests

8 new tests in test/sea/sea.js (grant/verify roundtrip, has() role+user matching, no-expiry, wrong administrator, expired, tampered, callback style, missing args). Full SEA suite: 43 passing / 1 pending / 0 failing.

SEA.role.grant(admin, userPub, role, opt) issues a self-contained role
token: the administrator signs { u: userPub, r: role, iat: now, exp }
with their private key. SEA.role.verify(token, adminPub) checks the
signature and expiry, returning the payload; SEA.role.has(token, role,
userPub, adminPub) is the boolean convenience check.

Tokens are verifiable anywhere the admin's public key is known, can be
stored in a 'roles node' (e.g. ~adminPub/roles/{role}) or handed
directly to users, and compose with SEA.certify for write-policy
enforcement. opt.expiry gives absolute expiry; 0/omitted = never
expires. opt.now (testing) allows clock-independent checks.

8 tests: grant/verify roundtrip, has() role+user matching, no-expiry,
wrong administrator, expired, tampered, callback style, missing args.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant