trana

Execution-time
authorization
for Solana.

Guard secures what can execute with one CPI call. Authority secures who can authorize: upgrades, mints, freezes, any PDA. Zero changes to the target program.

guard::enforce
slot317,409,221· live
01
Caller · signer
Wallet
7Tg…dmLmS · sends tx
signed
02
CPI · policy gate
Trana Guard
require · proof
pending
03
Your program
vault::withdraw
protected · executes on PASS
locked
guard · audit21:04:18 UTC
§ 01 THE ARCHITECTURE

Two primitives.
One authorization layer.

Guard secures what can execute. Authority secures who can authorize. Together they cover every privileged action on Solana: withdrawals, program upgrades, mint authority, admin keys.

PROGRAM 1 · trana_guard

Guard

Policy-gated instructions inside programs you own.

Code change3 accounts · 1 CPI
Best forCustom logic, conditional, embedded
SurfaceWithdraw, mint-by-rule, admin actions
use trana_guard::cpi::{enforce};

trana_guard::cpi::enforce(
    ctx.trana_ctx(),
    Policy::Require,
)?;

ctx.accounts.vault.withdraw(amount)?;

Reverts at the instruction boundary on missing proof.

PROGRAM 2 · trana_authority

Authority

Wraps any transferable authority, including code you don't own.

Code changezero · transfer authority to PDA
Best forUpgrade, mint, freeze, admin keys
SurfaceBPF Loader, SPL Token, any PDA
# transfer real authority to a Trana PDA — once
solana program set-upgrade-authority $PROGRAM \
  --new-upgrade-authority $TRANA_PDA

# now: leaked key cannot upgrade. only the PDA can.
#  and the PDA only signs after passkey proof.

The leaked admin key can request. It cannot authorize.

§ 02 HOW IT WORKS

A firewall between your
instruction and execution.

Guard sits between the transaction and your program logic. Every sensitive instruction evaluates a policy before it can run. No proof, no execution. The transaction reverts at the instruction boundary.

ix[N−2]
secp256r1::verify
native precompile · P-256 webauthn assertion
ix[N−1]
trana_guard::record_proof
writes proof to sysvar · sibling lookup
ix[N]
YOUR_PROGRAM::action
policy::Require · reads sibling proof · verifies binding
eval
✓ PASS
action executes
✕ BLOCK
tx reverts
PROTOCOL NOTE

Three instructions, one outcome.

Solana's secp256r1 verifier is a native precompile, not callable by CPI. Guard reads sibling top-level instructions via the Instructions sysvar, so the precompile and record_proof sit alongside your action in the same transaction.

BINDINGtx-hashEXPIRY120 slotsNONCEmonotonic
ENFORCEMENT MODEL

Signing ≠ authorization.

A leaked seed can sign anything. A guarded program demands a P-256 assertion, bound to this transaction, at execution time. Funds remain even when the keypair is public.

WHY NOW · SIMD-0075

Native secp256r1.

Solana shipped a P-256 verifier as a native precompile. The same curve WebAuthn uses. Passkeys verify on-chain in one instruction.

specSIMD-0075curvesecp256r1 / P-256activated2025 · mainnet-betaauthorOrion
§ 03THE GUARD'S RULESET

Four primitives.
Composable at the instruction level.

Each policy is a firewall rule. Stack them, branch them, sunset them. Every evaluation happens on-chain, every block.

policy::Requireunconditional gate

Requires a fresh passkey assertion before execution. No proof, no instruction. The strongest guarantee Trana ships.

credential = P-256 WebAuthn
binding = tx-hash
on_fail = REVERT(0xRequire)
View spec
policy::Limitamount ceiling

Caps SOL or SPL transfers per instruction. Below the threshold, no proof needed. Above it, the gate engages.

ceiling = 10.000 SOL
scope = per-instruction
on_breach = escalate → Require
View spec
policy::NotBeforetime lock

Locks the gate until slot N. Use it for unlock windows, vesting cliffs, and delayed admin actions. The cluster clock enforces it.

unlock = slot 317_500_000
eta = ~ 36h 14m
on_fail = REVERT(0xTooEarly)
View spec
policy::NotAfterautomatic sunset

Expires the gate at slot N. Session keys, time-boxed approvals, revocable delegation. All expire without a transaction.

expiry = slot 317_412_900
remaining = 3_679 slots
on_fail = REVERT(0xExpired)
View spec
§ 04 ONE CPI CALL

Three lines of Anchor.
Zero changes to your token logic.

Drop trana_guard::require at the top of your handler. Pass the guard PDA. Done. Your program is now protected by execution-time authorization without restructuring a single account.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// programs/vault/src/instructions/withdraw.rs use anchor_lang::prelude::*; use trana_guard::cpi::{require}}; pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> { trana_guard::require( &ctx.accounts.guard, &ctx.accounts.user, )?; token::transfer( ctx.accounts.into_transfer_context(), amount, )?; Ok(()) }
DIFF+3 lines · trana_guard::require−0 lines · token logic untouchedPROGRAM IDTRAqChewX8boPDuBbVXjS7iCQAnh9gDThfBRwXauwsG

Audited the macro.

require!expands to a single CPI to a single instruction on a single program. No magic accounts, no hidden upgrades. Read the lowering yourself.

Reverts cleanly.

On a missing or malformed proof, the action returns GuardError::ProofRequired. The transaction reverts at the instruction boundary. Nothing ever lands.

§ 05 EVIDENCE OF DEPLOYMENT

This is real infrastructure.
Verifiable from the chain up.

Program ID. Audit reports. License. The same fields you'd expect on a TLS chain — pinned to slots, not screenshots.

VALID
Program IDTRAqChewX8boPDuBbVXjS7iCQAnh9gDThfBRwXauwsGVerifiable on-chain · deployed on Solana devnet
LicenseMIT · open source · github.com/trana-soFull reference implementation including SDK & macro
DevnetLIVE since slot 314_204_911Continuous since 2026-04-12 · 0 incidents
AuditPlanned · before mainnet launchIndependent security review · report published before mainnet
SHA-256·55e9346fa6819eafd41d4e7043b3054b10ee546da8231eb8934a2ba0d83e034dsolscan ↗