← Back to Proposals

Role Separation & Warden-Based Auth v1 APPROVED — IMPLEMENTATION STARTED

Split administration from operation from consumption. Put Wardens at the trust edge, on-chain registries at the authority root. Prep the system for MainNet. — Approved April 18, 2026 · See Addendum v1 for open-question resolutions.

Status: all four open questions resolved. Independent manager keys · Sentry as extension-toggle capability · Admin 2nd-factor password + canary-phrase duress lockdown · DevNet admin-airdrop admission gate. Implementation begins with Track 1 (off-chain role plumbing). Progress log: /shardkeep/proposals/logs/v1.2.0-role-separation.log.
The core insight: Running master.chillxand.me as a Warden is a node operation. Setting reward config, managing treasury, tuning emissions, approving new Wardens — those are protocol governance. They share a server today, but they're two unrelated responsibilities and they should never have been collapsed into one UI. Before MainNet launches, we separate them permanently, and we distribute the auth surface across Wardens anchored by on-chain authority.

1. The Problem Today

Over-privileged operators break the decentralization story. Today, anyone with admin role in the 3Cs portal can see and modify anything in ShardKeep — nodes they don't own, economic parameters, other operators' stake, global network state. That is fine for a two-person team running the whole network. It is untenable the moment a third-party Bastion operator joins.

Four concrete symptoms, each traceable to the same root cause:

  1. Warden = Network Admin. The Warden running on master.chillxand.me is treated as both a network node and the global protocol administrator. Those are distinct responsibilities. A Warden operator should not automatically be a network admin.
  2. Operators can see/change anything. A portal admin is implicitly a ShardKeep admin. There is no scoping by node ownership, no filter by operator identity, no read-only mode for operators who only need to see their own data.
  3. Users see more than they need; operators see less than they need; admins see everything. The current /operator/ tree mixes protocol-governance pages (treasury, reward config, token) with per-node pages (stake, heartbeat). The /user/ tree shares plumbing with operator pages, risking data leaks.
  4. UI is cumbersome. Symptom of the role conflation. Fix the roles and each plane has one-third the surface area to display.

Beyond today's inconvenience, this becomes a security and reputation risk at MainNet launch:

2. Proposed Architecture — Three Planes, Five Menus

Design principle: Admin visibility flows down (admins can see operator aggregate data, read-only); operator visibility is sideways-isolated (operators see only their own nodes); user visibility is self-only (users see only their own vault). The planes never share a session, never share an interactive capability, and only share the minimal read paths needed for aggregate admin views.
Governance

Admin Plane

Protocol authority. Only 2 wallets for now.

  • Reward config, emissions, treasury
  • Proposals & governance
  • Global network dashboard (read-only across all nodes)
  • Approve pending Wardens
  • Emergency pause, slashing
  • Audit log
Operator

Warden Plane

One menu per Warden the wallet owns.

  • My Warden's uptime + earnings
  • My stake + unbond
  • Shard-routing policy settings
  • Manager wallet management
Operator

Bastion Plane

One menu per Bastion the wallet owns.

  • My Bastion's uptime + earnings
  • My stake, slashing history
  • Shard count / total bytes (opaque)
Operator

Sentry Plane

One menu per Sentry the wallet runs.

  • Tasks completed, points earned
  • Uptime
  • Small bond management
Consumer

User / Vault Plane

The end-user view. Already exists at /shardkeep/user/. Tighten scoping to eliminate shared includes with operator pages.

Multiple roles on one wallet

A single human may have more than one role — the most common case is the ShardKeep team: admin wallet + separate Warden operator wallet + possibly a personal vault wallet. After login, if a wallet qualifies for multiple planes, the user sees a role selector. Selecting a role scopes the session — switching planes requires re-selecting, not the session carrying both sets of capabilities simultaneously. Forces the mental separation.

3. Wallet Class Hierarchy

Three distinct wallet classes, each bound to a single role:

ClassPurposeSecurity postureSigns
User wallet Vault encryption key derivation + identity for User plane Hot (daily use). Phantom, Solflare, or hardware. Encryption-key derivation, subscription actions, vault reads
Operator wallet (cold) Holds the stake; identity for Warden/Bastion/Sentry plane Cold. Hardware wallet recommended. Minimally used. Node registration, stake changes, slashing-sensitive operations, manager-wallet binding
Manager wallet (hot) Day-to-day node operations without touching the cold wallet Hot. Can be a browser-extension keypair. Heartbeat acknowledgments, URL updates, non-critical config changes, routine JWT renewals
Why the manager wallet matters: Operators running Wardens should not need to re-sign with a hardware wallet every time their dashboard wants to refresh a JWT. The manager wallet is a registered hot key that can sign routine operations; the cold operator wallet only comes out for consequential decisions (stake changes, URL changes, exit). If the manager wallet leaks, the attacker cannot drain the stake or change the public URL — bounded blast radius.

Binding manager → operator

Each operator signs a one-time on-chain message with the operator wallet that says "pubkey M is my manager wallet for node N". The Warden registry stores this binding. Rotating a manager wallet is a re-signing by the operator wallet. Compromised manager wallet is revocable.

Sentry is an extension-level capability, not a separate wallet class

Resolved in Addendum v1 §6.1-Q2: The Sentry toggle is a property of the ShardKeep browser extension, not the User plane. Any wallet that has signed into the extension can flip "run a Sentry on my machine" — user, Warden operator, Bastion operator, even admin. The wallet-class separation rule is not violated because the Sentry capability is wallet-agnostic: the toggle lives wherever the wallet is. The $10 bond still applies; DevNet bond is airdropped by admin per §6a of this proposal.

4. DevNet First, MainNet Is a Cutover

All on-chain work happens on Solana DevNet first. Program IDs may churn as we iterate. When everything stabilizes, we re-deploy the same programs to mainnet-beta and flip a CLUSTER flag in client config. No database-allowlist stopgap, no "we'll move this on-chain later" debt.

Post-MainNet: both networks stay live. Per the decision recorded in the April status report, DevNet operation continues after MainNet launch. The client config exposes a cluster selector; users can run against either. This is load-bearing for continued development, training, and demos without touching real SHRD.

Config discipline

5. Geographic Warden Routing — No Auth Directors

Recommendation: The browser extension is the Warden router. No dedicated auth-director infrastructure is needed. The on-chain WardenRegistry is the source of truth; clients read it, pick the best Warden for their region, and cache the selection. For users without the extension, GeoDNS provides a convenience bootstrap.

Planned Warden deployment (one per approximate time zone, per prior discussion):

RegionFallback 1Fallback 2
PDT (Pacific)MDTCDT
MDT (Mountain) ← master.chillxand.mePDTCDT
CDT (Central)MDTEDT
EDT (Eastern)CDTUTC
UTC (EU)EDTAPAC
APACUTCPDT

Routing algorithm (client-side)

1. Read WardenRegistry from Solana RPC (cached locally for ≤ 5 minutes) 2. Filter to status = Active AND last_heartbeat_slot within 2h 3. Sort by region proximity (extension: browser tz; web: Accept-Language + Cloudflare-IP geo hint) 4. Ping top N candidates for latency (200–800ms cutoff) 5. Pick fastest. Cache for the session. On any auth failure, move to next.

Where the routing code lives

Why not dedicated auth-director servers?

Admin plane is exempt

There are literally two admin humans, and both of you know where your regional Wardens are. Admin UI routing can be hardcoded or an explicit picker. Keeps the admin surface smaller.

6. On-Chain Authority — AdminRegistry + WardenRegistry

A new Solana program (working name: shardkeep_authority) with two top-level PDAs.

AdminRegistry ON-CHAIN

AdminRegistry {
  admins:        Vec<AdminEntry>,     // v1: 2 entries
  threshold:     u8,                  // v1: 2-of-2 multisig for mutations
  created_at:    i64,
  updated_at:    i64,
}

AdminEntry {
  wallet:         Pubkey,
  added_at:       i64,
  duress_locked:  bool,               // set by flag_duress
  duress_since:   Option<i64>,
  duress_reason:  Option<String>,     // recorded on lift_duress
}

Operations:

The admin set is thus transparent, verifiable, and un-unilaterally-modifiable. No single Warden operator, no single compromised server, can add an admin. See Addendum §6.1 for the full canary-phrase duress design.

WardenRegistry ON-CHAIN

WardenEntry {
  node_pubkey:       Pubkey,          // Warden's node keypair — signs JWTs
  operator_wallet:   Pubkey,          // Cold wallet — signs stake/slashing ops
  manager_wallet:    Pubkey,          // Hot wallet — day-to-day ops
  public_url:        String,          // MUTABLE via update_url
  url_history:       Vec<UrlChange>,  // Last N URL values with timestamps
  cluster:           enum,            // DevNet | MainNet
  region_code:       String,          // ISO 3166-1 + TZ hint, e.g. "US-MDT"
  stake_amount:      u64,             // DevNet-SHRD (DevNet) OR SHRD (MainNet)
  status:            enum,            // Pending | Active | Probation | Slashed | Exited
  registered_at:     i64,
  last_heartbeat:    i64,             // Coarse, rate-limited to ~1/hour
  metadata_uri:      Option<String>,  // Optional off-chain metadata
}

Operations:

public_url is mutable, by design. We are currently on DevNet and may iterate on domain names before MainNet secures permanent domains. Changing a Warden's URL is a normal update_url op — not a program redeploy. Clients refresh the registry cache every ≤ 5 minutes, so URL changes propagate naturally. The url_history field lets clients display "this Warden was previously at X" during migrations and debugging.
Permissioned in v1.2 and v2.x; voted-admission deferred to v2.2+ follow-on proposal. Admin approval on new Wardens is the v1.2 / v2.0 / v2.1 (MainNet launch) security model. A dedicated follow-on proposal (v2.2+) introduces permissionless operator-voted admission using DevNet tenure + peer vouches + on-chain voting. See Addendum §6.2 for the pipeline shape. This proposal does not implement voted admission; it lays the schema groundwork.

Bootstrap

First deployment seeds both PDAs in a single genesis transaction: AdminRegistry with the two admin wallets, WardenRegistry with master.chillxand.me (or its successor URL per Addendum §6.2 domain flexibility) as Warden #1 on DevNet. Subsequent Wardens go through the apply → admin-approve flow — gated upstream by the DevNet admin-airdrop model described in §6a below.

6a. DevNet Admin-Airdrop Admission Gate

Resolved in Addendum v1 §6.2: DevNet is a fully admin-gated network. There is no faucet, no public mint, no self-serve path to obtain DevNet-SHRD. Every DevNet operator must be individually admin-onboarded. This is a deliberate network gate, not an implementation stopgap.

How a new DevNet operator is onboarded

  1. Prospective operator contacts admins out-of-band (Discord, email, signed message).
  2. Admin reviews request, verifies identity / introduces to existing operators / confirms node plan.
  3. Admin multisig signs airdrop_devnet_tokens(operator_wallet, amount, reason_uri) — DevNet-SHRD transferred to operator.
  4. Operator submits apply_warden(...) (or equivalent for Bastion/Sentry) using the airdropped tokens as bond.
  5. Admin multisig signs approve_warden(entry) — Pending → Active.
  6. Operator begins accumulating DevNet tenure, which will later count toward MainNet admission eligibility.

Why this is stronger than any bond-amount model

New DB + on-chain artifacts

ArtifactLocationPurpose
airdrop_devnet_tokensOn-chain instructionAdmin multisig signs; mints/transfers DevNet-SHRD to operator
shardkeep_devnet_airdropsOff-chain (mirrored from on-chain)Local table for audit + display: admin signer, operator, amount, reason, planned node type, airdrop timestamp
DevNet-SHRD mintOn-chain (SPL token)Separate mint from MainNet SHRD; used only on DevNet; admin-controlled mint authority

MainNet has no equivalent airdrop

MainNet SHRD is purchased from the market (or awarded via protocol emissions). There is no admin airdrop path on MainNet. The admission gate on MainNet is operator voting (v2.2+) that reads DevNet tenure as one of its inputs. DevNet is thus the onramp to MainNet operation.

7. Impersonation Defenses

A rogue Warden at fake.shardkeep.io cannot successfully phish a ShardKeep user/operator/admin thanks to a three-layer defense:

Layer 1 — Registry

Extension reads WardenRegistry. Rogue origin has no on-chain entry. Extension refuses to auto-route there and refuses to populate the auth flow.

Layer 2 — Origin check on sign

When any site requests a wallet signature, the extension's sign-hook compares the origin to registered Warden public_urls. Unregistered origin → red warning: "This site is not a registered ShardKeep Warden. Do not sign."

Layer 3 — JWT verification

A rogue Warden can sign its own JWTs, but no other Warden (and no other ShardKeep node) will accept them because its node_pubkey isn't in the registry. JWTs are worthless outside the rogue server's own domain.

Additional hardening

Duress Alert Channel

Canary-phrase events trigger out-of-band alerts in addition to the on-chain flag. Per Addendum v1 §2.4, when any admin wallet enters its canary phrase at any Warden, the following happens in parallel with the on-chain flag_duress instruction: The alert is silent on the attacker's side — the duress UI shows a normal-looking admin session. Alerts only go to pre-registered out-of-band contacts.

Non-admin plane continuation under duress

Two-tier response (Addendum §6.1): While the admin plane is fully locked for a duress-flagged wallet, every other plane that wallet has access to (Warden/Bastion/Sentry/User) shows a prominent red banner: "This wallet is currently flagged as duress-locked on the network. Your operations will be broadcast-acknowledged on-chain and visible to every other Warden. Do you want to continue?" The user must sign a duress_ack message with their wallet to proceed for the session. Acks are posted on-chain via record_duress_ack and mirrored to every Warden's audit log — so coercer pivots into operator/user planes are publicly witnessed even though they aren't operationally blocked.

8. Directory Restructure

/var/www/shared/shardkeep/
  admin/                  ← NEW. Protocol governance. Gated: admin registry + admin pwd.
    index.php             (global network, aggregate stats)
    treasury.php          (moved from /operator/treasury.php)
    reward-config.php     (moved from /operator/epochs.php + token.php)
    proposals/            (governance proposals UI)
    wardens.php           (read-only view of all Wardens; approve pending)
    audit.php             (logs)
  warden/                 ← NEW. Gated: wallet owns a Warden node.
    index.php             (MY Warden's dashboard)
    staking.php           (MY stake, earnings, unbond)
    settings.php          (manager wallet, URL change)
  bastion/                ← NEW. Same pattern, scoped to Bastion nodes.
    index.php
    staking.php
    settings.php
  sentry/                 ← NEW. Same pattern, scoped to Sentry nodes.
    index.php
    tasks.php
    staking.php
  user/                   ← Keeps. Tighten scoping.
    index.php             (vault)
    settings.php
    sentry.php            (opt-in to running a Sentry — single blessed overlap)

  operator/               ← DEPRECATED. Split content into admin/warden/bastion/sentry.
                          Its api/ tree becomes the shared backend for all planes.
                          Eventually rename to /api/ + /engine/ to reflect reality.
Less code after this, not more. The role conflation means existing pages try to serve multiple audiences at once with conditional rendering. Splitting them results in simpler, narrower pages — each doing one job well for one audience.

9. Implementation Tracks

Track 1 — Role model + auth plumbing OFF-CHAIN

Track 2 — Four-menu UI split REFACTOR

Track 3 — Solana programs on DevNet ON-CHAIN

Track 4 — Extension as Warden router + impersonation guard NEW FEATURE

Track 5 — Warden-to-Warden trust glue HYBRID

Release plan

VersionContentsClusterAdmission model
v1.2.0 — The Great Role SplitTracks 1 + 2. Off-chain role plumbing + UI split. Canary-phrase scaffold.DevNet (existing)Admin-approved
v2.0.0 — On-Chain AuthorityTracks 3 + 4 + 5. AdminRegistry + WardenRegistry deployed. Extension becomes router. DevNet-SHRD mint live. Duress mechanisms fully on-chain.DevNet stabilizationAdmin-approved; admin-airdrop gate active
v2.1.0 — MainNet LaunchSame codebase, same programs, redeployed to mainnet-beta. Cluster selector in client. DevNet and MainNet both live.MainNet + DevNet both liveAdmin-approved on both clusters
v2.2+ — Voted Admission (follow-on proposal)Separate dedicated proposal. Introduces operator-voted permissionless MainNet Warden admission. Reads DevNet tenure + peer vouches. Out of scope for this proposal.MainNetOperator-voted
Why defer voted admission: implementing the voting mechanics, vouching UI, discord-bot engagement tracking, and OperatorProfile PDA is a meaningful chunk of work that doesn't need to block MainNet launch. The DevNet admin-gate model (§6a) already provides strong Sybil resistance. We ship MainNet with admin-approved admission, observe real operator behavior for 30-60 days, then land voted admission with real data informing the parameters.

10. Open Decisions (All Resolved)

All four open questions were resolved on April 18, 2026. Full decision rationale in Addendum v1. Summary below.

Open #1 — Manager wallet derivation RESOLVED

Decision: Independent keys. The operator wallet signs a one-time on-chain registration message binding the manager pubkey. Cleaner security boundary; compromise of manager wallet cannot compromise operator wallet; rotation is a new binding signature. See Addendum §1.

Open #2 — Sentry operated by user wallet RESOLVED

Decision: Sentry is an extension-level capability, not a wallet-class exception. Any wallet that has signed into the extension can flip the Sentry toggle — user, Warden operator, Bastion operator, or admin. The wallet-class separation rule is not violated because the Sentry capability is wallet-agnostic. See Addendum §1 and §3 of this proposal.

Open #3 — Admin plane 2nd-factor + canary phrase RESOLVED

Decision: Yes to 2nd-factor password, and a canary-phrase duress-lockdown mechanism on top of it. Admin plane fully locks under duress; every other plane for that wallet shows a red banner requiring a signed duress_ack posted on-chain. Both-admins-coerced nuclear case mitigated via a time-locked recovery wallet (v2.0). See Addendum §2 and §6.1 for full design.

Open #4 — When does Warden admission become permissionless? RESOLVED

Decision: Permissionless MainNet admission is a separate follow-on proposal (v2.2+), not part of v1.2 or v2.0 scope. This proposal lays the schema groundwork (WardenEntry has all needed fields). The follow-on will introduce operator-voted admission reading DevNet tenure + peer vouches + on-chain voting. Critically: the DevNet admin-airdrop gate (§6a) means every DevNet operator has already been admin-vetted, so voted-admission doesn't cold-start against Sybil risk. See Addendum §3 and §6.2 for pipeline design.

11. Risks & Mitigations

RiskLikelihoodMitigation
Track 2 refactor breaks existing flows (ACL migration, node views, etc.) Medium Comprehensive audit of every consumer of /operator/ before moves. Integration tests. Staged rollout: ship /admin/ and /warden/ first; keep /operator/ as a redirect shim until /bastion/ + /sentry/ ship.
On-chain program has a bug discovered post-deploy Medium DevNet-first gives us a free iteration ground. Include a one-time admin_emergency_migrate instruction that lets the admin multisig bulk-migrate state to a new program version. Removed before MainNet launch.
Operators running Wardens see "their dashboard suddenly shows less" after the role split Certain (by design) Comms + migration doc + in-UI banner explaining the split. Emphasize that the reduction is decentralization, not loss of capability. Admins still have full visibility — they just reach it from a separate menu.
Extension v2 rollout creates support burden (users on old extension) Medium Extension v1.1.6 already has a version-check mechanism. Force-update cadence: 30-day grace; v1 refuses to authenticate against v2.0.0 Wardens after grace.
Geographic Warden deployment slower than expected — only one Warden live at MainNet High (near-term reality) Architecture accommodates a single Warden. GeoDNS + registry gracefully degrade to "the only live Warden." Ship with 1, scale as operators come online.
Both admins coerced into canary-lockdown simultaneously Very low (requires coordinated physical attack on both admins) Time-locked recovery wallet. A third key held in cold physical storage (hardware wallet in a safe) that, after a 7-day on-chain waiting period and three confirmations from the recovery wallet itself, can unilaterally lift all duress flags via time_locked_recovery_lift. Not v1.2-critical; lands in v2.0 with the on-chain programs. See Addendum §2.6.
DevNet admin-airdrop becomes a bottleneck as the operator pool grows Medium (as ShardKeep gains adoption) Admins are the intentional rate limiter early on — this is a feature. If onboarding volume outpaces admin capacity, introduce a "warden-vouched airdrop" tier where an existing-admin-vetted Warden can airdrop (smaller amount) to a new operator subject to post-hoc admin review. Landed in v2.2+ voted-admission proposal.

12. Definition of Done

v1.2.0 done: Four distinct menus rendered for the appropriate wallets. A Bastion operator account cannot see treasury/reward-config UI. A user account cannot see any operator or admin UI. Admin wallets continue to see the admin plane. All tests pass on DevNet.
v2.0.0 done: AdminRegistry and WardenRegistry live on DevNet. master.chillxand.me registered as Warden #1. Extension v2 routes via registry. JWTs signed by Warden node keys verifiable by any other Warden. Impersonation warnings functional against a test rogue origin.
v2.1.0 / MainNet done: Programs deployed to mainnet-beta. Cluster selector in client config. First two operators (beyond yourself) onboarded through the apply → admin-approve flow. Real SHRD staked. DevNet continues operating in parallel.

13. What Happens Next

Approved April 18, 2026. Implementation has started:

  1. Progress log created at /var/www/shared/shardkeep/proposals/logs/v1.2.0-role-separation.log. Log is visible from the proposals index via the existing progress-log viewer convention.
  2. Track 1 (off-chain role plumbing) is in progress — wallet-class schema, auth helpers, temporary admin allowlist, duress-ack scaffold.
  3. Track 2 (four-menu UI split) begins when Track 1 plumbing is in place.
  4. Track 3 (Solana programs on DevNet) starts in parallel on a separate working branch.
  5. The shardkeep_authority program will be the first on-chain artifact of the great role split, deployed to Solana DevNet.

14. Follow-On Work (Out of Scope for This Proposal)

Items explicitly deferred to dedicated follow-on proposals:

Follow-on #1 — Voted MainNet Warden Admission FUTURE (v2.2+)

Implements operator-voted permissionless MainNet Warden admission. Reads DevNet tenure (on-chain) + peer vouches (OperatorProfile PDA) + engagement signals. 60%-quorum / 2/3-threshold voting with admin veto retained until ≥20 MainNet Wardens. Design detail in Addendum §6.2. Prerequisite: ≥3 MainNet Wardens live + ≥60 days of operator-community history.

Follow-on #2 — Time-Locked Recovery Wallet FUTURE (v2.0)

Third cold-storage key used for the nuclear "both admins coerced simultaneously" recovery scenario. 7-day on-chain waiting period + three confirmations from the recovery wallet itself clears all duress flags via time_locked_recovery_lift. Lands with the on-chain programs in v2.0.

Follow-on #3 — OperatorProfile PDA + Peer Vouching FUTURE (v2.2+)

On-chain operator identity with self-chosen handle, nodes operated, vouches given/received, last-active timestamp. Reads into the voted-admission pipeline. Also surfaces in operator UIs for community visibility. Scoped with the voted-admission proposal.

Proposed: April 18, 2026 · Approved: April 18, 2026 · Status: Implementation in progress — Track 1 · See: Addendum v1