Authorization signatures
Securing Privy API requests with authorization signatures
Authorization signatures protect your resources and wallet operations by cryptographically signing API requests. When enabled, these signatures prevent malicious actors from tampering with your request payload or forging requests to your wallets, ensuring that only authorized servers can trigger wallet actions.
Authorization signatures are a security feature used to secure update requests to all critical resources.
Required headers
When using authorization signatures, include the following header with your request:
The authorization signature. If multiple signatures are required, they should be comma separated.
When are they necessary?
Modifying resources
All critical resources have an owner_id
field, which indicates the authorization key or quorum whose signatures are required in order to modify the given resource.
This means, if the owner_id
is set, authorization signatures are required for all PATCH
and DELETE
requests to the resource.
Key quorums do not have owners, but rather require a satisfaying set of signatures from the key quorum itself.
You can add additional, non-owner, signers to a wallet by specifying them in the additional_signers field on the wallet resource.
Taking actions with wallets
Signatures from the wallet’s owner are required to take actions on a wallet by default. If an owner_id
is set, authorization signatures are required for:
- POST requests to
/v1/wallets/<wallet_id>/rpc
Authorization signatures are an important security measure and we strongly recommend registering authorization keys for all production resources.
How to use authorization signatures
In order to use authorization signatures, you need to:
- Create an authorization key.
- Register the authorization public key with the resource you wish to protect.
- Begin using the authorization private key to sign requests via the
privy-authorization-signature
header.
Creating authorization keys
To create a new authorization key via the Dashboard:
- Visit the Authorization keys page in the Dashboard.
- Click the New key button.
- Copy and save the generated Private key.
Read more about creating authorization keys.
The private key (e.g. the Authorization key you copy) is generated on your device. Privy only receives the public key for registration. The private key never leaves the client.
Registering authorization keys
To register an authorization key with a resource, you need to specify the public key in the owner
field when creating a resource (e.g. wallet or policy).
Generating signatures
You can generate authorization signatures in three ways:
- Using
PrivyClient
via the Server SDK.PrivyClient
will automatically inject authorization signatures when required. Learn more. - Using utility functions from the Server SDK such as
formatRequestForAuthorizationSignature
andgenerateAuthorizationSignature
. - Implementing your own signing logic.
Follow the steps below to generate an authorization signature with Server SDK utility functions or your own signing logic:
Build Payload
Generate a JSON payload containing the following fields. All fields are required unless otherwise specified.
Field | Type | Description | |||
---|---|---|---|---|---|
version | 1 | Authorization signature version. Currently, 1 is the only version. | |||
method | `‘POST' | 'PUT' | 'PATCH' | 'DELETE’` | HTTP method for the request. Signatures are not required on 'GET' requests. |
url | string | The full URL for the request. Should not include a trailing slash. | |||
body | JSON | JSON body for the request. | |||
headers | JSON | JSON object containing any Privy-specific headers, e.g. those that are prefixed with 'privy-' . This should not include any other headers, such as authentication headers, content-type , or trace headers. | |||
headers['privy-app-id'] | string | Privy app ID header (required). | |||
headers['privy-idempotency-key'] | string | Privy idempotency key header (optional). If the request does not contain an idempotency key, leave this field out of the payload. |
Format Payload
Canonicalize the payload per RFC 8785 and serialize it to a string. This GitHub repository links to various libraries for JSON canonicalization in different languages.
Sign Payload
Sign the serialized JSON with ECDSA P-256 using your app’s private key and serialize it to a base64-encoded string.
Examples
We recommend using PrivyClient
to send WalletApi requests, which will automatically inject authorization signatures when required.
However, if you must send WalletApi requests without PrivyClient
, we recommend using generateAuthorizationSignature
to sign the request or formatRequestForAuthorizationSignature
to format and serialize the request if you need to sign elsewhere.
We recommend using PrivyClient
to send WalletApi requests, which will automatically inject authorization signatures when required.
However, if you must send WalletApi requests without PrivyClient
, we recommend using generateAuthorizationSignature
to sign the request or formatRequestForAuthorizationSignature
to format and serialize the request if you need to sign elsewhere.