- one authority
- one stable
role_id - one or more permission actions
Authority types
Swig currently supports these authority families:
Session-based authorities keep the same role and permission model, but switch
authentication to a time-bounded session key or session rule.
What ProgramExec means
ProgramExec is the least familiar authority type, but it matters for recovery
and other protocol-controlled flows.
Instead of authenticating a user signature directly, it authenticates against
another instruction in the same transaction. The configured authority stores:
- the expected program ID
- an instruction-prefix match
- optional instruction-index targeting through the authority payload
Permission families
Actions are typed permission records attached to roles.Time-based limits are measured in slots
Every time-bounded permission in Swig counts slots, not seconds. This applies toSolRecurringLimit, TokenRecurringLimit, StakeRecurringLimit,
their destination variants, and session durations on *Session authorities.
A window is stored as a fixed slot count and does not rescale when slot time
changes. A monthly subscription sized at 400ms already resets closer to every
26 days, and will reset every 15 days once slot time reaches 200ms. This
affects wallets that already exist as well as new ones.
Which way the drift cuts
The two permission families fail in opposite directions, so round accordingly:- Recurring spend limits reset more often than intended. The role can spend more per calendar month than you granted. This is the over-permissive direction — size for 200ms to stay conservative.
- Session durations expire sooner than intended. Sessions are shorter, not longer, so the risk is a broken flow rather than a widened one. Size for 400ms and re-issue sessions on expiry.
Working with the drift
- Do not hardcode a slots-per-second constant. Derive it at configuration time
by sampling
getBlockTimeacross a known slot delta, or read it from a config value you can update without redeploying. - Prefer shorter windows that you renew, over long windows sized once. A one-day window drifts by hours; a one-year window drifts by months.
- If a permission must track a real calendar period, enforce that period in your own service and use the on-chain window as an upper bound, not as the clock.
- Re-check windows on existing wallets at each rollout step. Updating a role’s
actions requires
ManageAuthority.
Permission distinctions that matter
Allis the broadest role marker.AllButManageAuthoritystill allows broad execution, but excludes authority and sub-account management.ManageAuthorityis for adding, removing, or updating authorities.RecoveryAuthorityis narrower thanManageAuthority. It only grants access to the dedicated recovery path.ProgramAllgrants effectively unrestricted CPI access and should be treated as highly privileged.ProgramCuratedis looser than per-program rules, but still not fully open.ProgramScopeis the narrowest program control. It binds a program, a target account, and numeric field offsets so the program can enforce scoped limits.
Common role shapes
Most real integrations end up with some mix of:- an admin role that can manage authorities
- an execution role that carries spend and program permissions
- one or more session-capable roles for short-lived delegated access
- an optional recovery role with
RecoveryAuthority
How this maps to higher-level SDKs
Higher-level SDKs may hide the byte layout, but they still depend on the same rules:- a wallet operation eventually targets one role
- that role authenticates through one authority type
- that role’s actions decide whether execution is allowed

