Auth0Guard
The Auth0Guard contract verifies JWT tokens issued by Auth0. It implements the JwtGuard trait for RS256 signature verification and validates a custom fatxn claim to ensure the signed transaction matches what was authorized by the user.
Features
- Owner-only access control for administrative functions (updating public keys, changing owner).
- Verifies JWT signatures using the RS256 algorithm with multiple public keys.
- Validates the
fatxncustom claim against the sign payload. - Validates standard JWT claims (issuer, expiration, not-before).
- Supports contract upgrades with state migration.
Contract State
| Field | Type | Description |
|---|---|---|
public_keys | Vec<JwtPublicKey> | List of RSA public keys for signature verification |
owner | AccountId | The contract owner with administrative privileges |
JwtPublicKey Structure
pub struct JwtPublicKey {
pub n: Vec<u8>, // RSA modulus
pub e: Vec<u8>, // RSA exponent
}
Initialization
#[init]
pub fn init(owner: AccountId, public_keys: Vec<JwtPublicKey>) -> Self
owner: The account that will have administrative privileges.public_keys: The RSA public key components for JWT verification.
All public keys are validated on initialization.
Public Key Management
In case of a security breach or key rotation policy, the contract owner can update the RSA public keys:
pub fn set_public_keys(&mut self, public_keys: Vec<JwtPublicKey>)
Only the owner of the contract can update the RSA public key components.
Verification Logic
The verify function is called by the FastAuth or JwtGuardRouter contract:
pub fn verify(&self, issuer: String, jwt: String, sign_payload: Vec<u8>, predecessor: AccountId) -> (bool, String)
issuer: The expected JWT issuer (e.g.,https://dev-xxx.us.auth0.com/).jwt: The JWT token to verify.sign_payload: The payload to verify against thefatxnclaim.predecessor: The original caller's account ID.
Returns:
bool: Whether the JWT is valid.String: The subject (sub) claim if valid, or an error message.
Verification Steps
- Size Check: JWT must not exceed 7KB.
- Signature Verification: Verifies the RS256 signature against any of the stored public keys.
- Claims Validation:
iss: Must match the provided issuer.exp: Token must not be expired.nbf: Token must be valid (not before current time).
- Custom Claims Verification: The
fatxnclaim must match thesign_payload.
Custom Claims Structure
pub struct CustomClaims {
pub fatxn: Vec<u8>,
}
The fatxn (FastAuth Transaction) claim contains the serialized transaction payload that the user authorized. This ensures that the JWT can only be used to sign the specific transaction it was issued for.
Ownership Management
Querying Owner
pub fn owner(&self) -> AccountId
Changing Owner
pub fn change_owner(&mut self, new_owner: AccountId)
Only the current owner can change ownership.
Contract Upgrades
The owner can upgrade the contract:
pub fn update_contract(&self) -> Promise
Usage Example
A typical verification flow:
- User authenticates with Auth0 and requests a JWT with the
fatxnclaim containing their transaction data. - User calls
FastAuth.sign()withguard_id: "jwt#auth0", their JWT, and the sign payload. FastAuthroutes toJwtGuardRouter, which routes toAuth0Guard.Auth0Guardverifies the JWT signature and checks thatfatxnmatchessign_payload.- On success, the user's
subclaim is returned and used to derive the MPC signing path.