Skip to main content

Policy language

This page provides an overview of how to author policies using our policy language. To begin, we'll need to get familiar with the language's grammar, keywords, and types.

Grammar

The grammar has been designed for flexibility and expressiveness. We currently support the following operations:

OperationOperatorsExampleTypes
logical&&, ||"true && false"(bool, bool) -> bool
comparison==, !=, <, >, <=, >="1 < 2"(int, int) -> bool
comparison==, !="'a' != 'b'"(string, string) -> bool
comparisonin"1 in [1, 2, 3]"(T, list<T>) -> bool
accessx[<index>][1,2,3][0](list<T>) -> T
accessx[<index>]"'abc'[0]"(string) -> string
accessx[<start>..<end>][1,2,3][0..2](list<T>) -> (list<T>)
accessx[<start>..<end>]"'abc'[0..2]"(string) -> string
accessx.<field>"user.tags"(struct) -> T
functionx.all(item, <predicate>)"[1,1,1].all(x, x == 1)"(list<T>) -> bool
functionx.any(item, <predicate>)"[1,2,3].any(x, x == 1)"(list<T>) -> bool
functionx.contains(<value>)"[1,2,3].contains(1)"(list<T>) -> bool
functionx.count()"[1,2,3].count()"(list<T>) -> int
functionx.filter(item, <predicate>)"[1,2,3].filter(x, x == 1)"(list<T>) -> (list<T>)

Keywords

Keywords are reserved words that are dynamically interchanged for real values at evaluation time. Each field supports a different set of keywords.

Consensus

KeywordTypeDescription
approverslist<User>The users that have approved an activity

Condition

KeywordTypeDescription
activityActivityThe activity metadata of the request
eth.txEthereumTransactionThe parsed Ethereum transaction payload (see Appendix below)
solana.txSolanaTransactionThe parsed Solana transaction payload (see Appendix below)
walletWalletThe target wallet used in sign requests
private_keyPrivateKeyThe target private key used in sign requests

Types

The language is strongly typed which makes policies easy to author and maintain.

Primitive

TypeExampleNotes
booltrue
int256i128
string'a'only single quotes are supported
list<T>[1, 2, 3]a list of type T
struct{ id: 'abc' }a key-value map of { field:T } (defined below)

Struct

StructFieldTypeDescription
UseridstringThe identifier of the user
tagslist<string>The collection of tags for the user
emailstringThe email address of the user
aliasstringThe alias of the user
ActivitytypestringThe type of the activity (e.g. ACTIVITY_TYPE_SIGN_TRANSACTION_V2)
resourcestringThe resource type the activity targets: USER, PRIVATE_KEY, POLICY, WALLET, ORGANIZATION, INVITATION, CREDENTIAL, CONFIG, RECOVERY, AUTH, PAYMENT_ACTION, SUBSCRIPTION
actionstringThe action of the activity: CREATE, UPDATE, DELETE, SIGN, EXPORT, IMPORT
WalletidstringThe identifier of the wallet
PrivateKeyidstringThe identifier of the private key
tagslist<string>The collection of tags for the private key
EthereumTransactionfromstringThe sender address of the transaction
tostringThe receiver address of the transaction (can be an EOA or smart contract)
datastringThe arbitrary calldata of the transaction (hex-encoded)
valueintThe amount being sent (in wei)
gasintThe maximum allowed gas for the transaction
gas_priceintThe price of gas for the transaction
chain_idintThe chain identifier for the transaction
nonceintThe nonce for the transaction
SolanaTransactionaccount_keyslist<string>The accounts (public keys) involved in the transaction
program_keyslist<string>The programs (public keys) involved in the transaction
instructionslist<Instruction>A list of Instructions (see below)
transferslist<Transfer>A list of Transfers (see below)
recent_blockhashstringThe recent blockhash specified in a transaction

Nested Structs

StructFieldTypeDescription
Instructionprogram_keystringThe program (public key) involved in the instruction
accountslist<Account>A list of Accounts involved in the instruction
instruction_data_hexstringRaw hex bytes corresponding to instruction data
address_table_lookupslist<AddressTableLookup>A list of AddressTableLookups used in the instruction. Learn more here
TransfersenderstringA Solana account (public key)
recipientstringA Solana account (public key)
amountstringThe native SOL amount for the transfer (lamports)
Accountaccount_keystringA Solana account (public key)
signerbooleanAn indicator of whether or not the account is a signer
writablebooleanAn indicator of whether or not the account can perform a write operation
AddressTableLookupaddress_table_keystringA Solana address (public key) corresponding to the address table
writable_indexeslist<int>Indexes corresponding to accounts that can perform writes
readonly_indexeslist<int>Indexes corresponding to accounts that can only perform reads

Activity Breakdown

Resource TypeActionActivity Type
ORGANIZATIONCREATEACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7
UPDATEACTIVITY_TYPE_UPDATE_ROOT_QUORUM
UPDATEACTIVITY_TYPE_SET_ORGANIZATION_FEATURE
REMOVEACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE
INVITATIONCREATEACTIVITY_TYPE_CREATE_INVITATIONS
DELETEACTIVITY_TYPE_DELETE_INVITATION
ACCEPTACTIVITY_TYPE_ACCEPT_INVITATION_V2
POLICYCREATEACTIVITY_TYPE_CREATE_POLICY_V3
CREATEACTIVITY_TYPE_CREATE_POLICIES
UPDATEACTIVITY_TYPE_UPDATE_POLICY
DELETEACTIVITY_TYPE_DELETE_POLICY
WALLETCREATEACTIVITY_TYPE_CREATE_WALLET
CREATEACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS
EXPORTACTIVITY_TYPE_EXPORT_WALLET
EXPORTACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT
IMPORTACTIVITY_TYPE_INIT_IMPORT_WALLET
IMPORTACTIVITY_TYPE_IMPORT_WALLET
PRIVATE_KEYCREATEACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2
CREATEACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG
UPDATEACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG
DELETEACTIVITY_TYPE_DISABLE_PRIVATE_KEY
DELETEACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS
EXPORTACTIVITY_TYPE_EXPORT_PRIVATE_KEY
IMPORTACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY
IMPORTACTIVITY_TYPE_IMPORT_PRIVATE_KEY
SIGNACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2
SIGNACTIVITY_TYPE_SIGN_TRANSACTION_V2
USERCREATEACTIVITY_TYPE_CREATE_USERS_V2
CREATEACTIVITY_TYPE_CREATE_USER_TAG
CREATEACTIVITY_TYPE_CREATE_API_ONLY_USERS
UPDATEACTIVITY_TYPE_UPDATE_USER
UPDATEACTIVITY_TYPE_UPDATE_USER_TAG
DELETEACTIVITY_TYPE_DELETE_USERS
DELETEACTIVITY_TYPE_DELETE_USER_TAGS
UPDATEACTIVITY_TYPE_RECOVER_USER
CREDENTIALCREATEACTIVITY_TYPE_CREATE_API_KEYS
CREATEACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2
DELETEACTIVITY_TYPE_DELETE_API_KEYS
DELETEACTIVITY_TYPE_DELETE_AUTHENTICATORS
PAYMENTUPDATEACTIVITY_TYPE_SET_PAYMENT_METHOD_V2
DELETEACTIVITY_TYPE_DELETE_PAYMENT_METHOD
SUBSCRIPTIONUPDATEACTIVITY_TYPE_ACTIVATE_BILLING_TIER
CONFIGUPDATEACTIVITY_TYPE_UPDATE_ALLOWED_ORIGINS
RECOVERYUPDATEACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY
AUTHCREATEACTIVITY_TYPE_EMAIL_AUTH
CREATEACTIVITY_TYPE_OAUTH
CREATEACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS
DELETEACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS

Appendix

Root quorum activities

There are a select few activities that are not governed by policies, but rather by an organization's root quorum. These activities are: ACTIVITY_TYPE_UPDATE_ROOT_QUORUM, ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE, ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE. For example, if a policy is added that allows a specific non-root user to perform ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE activities, these requests will still fail as they are subject specifically to root quorum.

Ethereum

Our Ethereum policy language (accessible via eth.tx) allows for the granular governance of signing Ethereum (EVM-compatible) transactions. Our policy engine exposes a fairly standard set of properties belonging to a transaction.

See the Policy examples for sample scenarios.

Solana

Similarly, our Solana policy language (accessible via solana.tx) allows for control over signing Solana transactions. Note that there are some fundamental differences between the architecture of the two types of transactions, hence the resulting differences in policy structure. Notably, within our policy engine, a Solana transaction contains a list of Transfers, currently corresponding to native SOL transfers. Each transfer within a transaction is considered a separate entity. Here are some approaches you might take to govern native SOL transfers:

  • All transfers need to match the policy condition. Useful for allowlists (example)
  • Just one transfer needs to match the policy condition. Useful for blocklists (example)
  • Only match if there is a single transfer in the transaction, and that transfer meets the criteria (example). This is the most secure approach, and thus most restrictive.

See the Policy examples for sample scenarios.