Securing Privy API requests with authorization signatures
Authorization keys provide an additional layer of security for actions taken by your app’s wallets. These cryptographic keys help ensure that only actions explicitly authorized by your server are executed on user wallets.
When you specify an owner of a resource, all requests to update that resource must be signed with the associated key. Requests to take actions with a wallet must also be signed by the wallet’s owner. This security measure verifies that each request comes from your authorized backend systems and helps prevent unauthorized operations.
Authorization signatures are a security feature used to secure update requests to all critical resources. Actions on user wallets typically require authorization signatures.
When using authorization signatures, include the following header with your request:
The authorization signature. If multiple signatures are required, they should be comma separated.
If you are using Privy’s SDKs, the appropriate authorization signature header is added automatically to your requests.
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.
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:
/v1/wallets/<wallet_id>/rpc
Authorization signatures are an important security measure and we strongly recommend registering authorization keys for all production resources.
In order to use authorization signatures, you need to:
privy-authorization-signature
header.App-managed authorization keys are authorization keys controlled directly by your application. If your app manages an authorization key that is set as the owner of a resource, then your app controls the resource.
To create a new authorization key via the Dashboard:
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.
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).
App-managed authorization keys are authorization keys controlled directly by your application. If your app manages an authorization key that is set as the owner of a resource, then your app controls the resource.
To create a new authorization key via the Dashboard:
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.
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).
Directly managing user authorization keys via the REST API is an advanced integration. If you are using a Privy SDK, you do not need to directly manage the user’s authorization key or manually generate authorization signatures.
Privy enables authenticated users to fully control their wallets.
In particular, Privy issues time-bound authorization keys to users who authenticate via a verified JWT. The user authorization key is used to sign requests to the Privy API. Typically, user authorization keys are internally managed within Privy SDKs.
If SDK support is unavailable, you can directly retrieve a user authorization key by making a request to POST /wallets/authenticate
with a valid user JWT.
You can generate authorization signatures in three ways:
PrivyClient
from the NodeJS SDK
. Privy SDKs will automatically inject authorization signatures when required. Learn more.formatRequestForAuthorizationSignature
and generateAuthorizationSignature
.Follow the steps below to generate an authorization signature with 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.
To make requests to the Privy API, we recommend using PrivyClient
, which will automatically inject authorization signatures when required.
However, if you must send API 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.
To make requests to the Privy API, we recommend using PrivyClient
, which will automatically inject authorization signatures when required.
However, if you must send API 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.
Privy client SDKs enable you to authorize API requests using the user’s time-bound authorization key. Typically, this interface is used to sign user-authorized requests, which are then sent to the Privy API.
To sign a request with your user’s authorization key, use the useAuthorizationSignature
hook. This hook exposes an interface to access the public key of the user’s authorization key and to request signatures using the authorization key.
Include the resulting authorization signature as a request header when making requests to the Privy API to modify resources owned by the user.
Securing Privy API requests with authorization signatures
Authorization keys provide an additional layer of security for actions taken by your app’s wallets. These cryptographic keys help ensure that only actions explicitly authorized by your server are executed on user wallets.
When you specify an owner of a resource, all requests to update that resource must be signed with the associated key. Requests to take actions with a wallet must also be signed by the wallet’s owner. This security measure verifies that each request comes from your authorized backend systems and helps prevent unauthorized operations.
Authorization signatures are a security feature used to secure update requests to all critical resources. Actions on user wallets typically require authorization signatures.
When using authorization signatures, include the following header with your request:
The authorization signature. If multiple signatures are required, they should be comma separated.
If you are using Privy’s SDKs, the appropriate authorization signature header is added automatically to your requests.
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.
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:
/v1/wallets/<wallet_id>/rpc
Authorization signatures are an important security measure and we strongly recommend registering authorization keys for all production resources.
In order to use authorization signatures, you need to:
privy-authorization-signature
header.App-managed authorization keys are authorization keys controlled directly by your application. If your app manages an authorization key that is set as the owner of a resource, then your app controls the resource.
To create a new authorization key via the Dashboard:
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.
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).
App-managed authorization keys are authorization keys controlled directly by your application. If your app manages an authorization key that is set as the owner of a resource, then your app controls the resource.
To create a new authorization key via the Dashboard:
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.
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).
Directly managing user authorization keys via the REST API is an advanced integration. If you are using a Privy SDK, you do not need to directly manage the user’s authorization key or manually generate authorization signatures.
Privy enables authenticated users to fully control their wallets.
In particular, Privy issues time-bound authorization keys to users who authenticate via a verified JWT. The user authorization key is used to sign requests to the Privy API. Typically, user authorization keys are internally managed within Privy SDKs.
If SDK support is unavailable, you can directly retrieve a user authorization key by making a request to POST /wallets/authenticate
with a valid user JWT.
You can generate authorization signatures in three ways:
PrivyClient
from the NodeJS SDK
. Privy SDKs will automatically inject authorization signatures when required. Learn more.formatRequestForAuthorizationSignature
and generateAuthorizationSignature
.Follow the steps below to generate an authorization signature with 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.
To make requests to the Privy API, we recommend using PrivyClient
, which will automatically inject authorization signatures when required.
However, if you must send API 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.
To make requests to the Privy API, we recommend using PrivyClient
, which will automatically inject authorization signatures when required.
However, if you must send API 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.
Privy client SDKs enable you to authorize API requests using the user’s time-bound authorization key. Typically, this interface is used to sign user-authorized requests, which are then sent to the Privy API.
To sign a request with your user’s authorization key, use the useAuthorizationSignature
hook. This hook exposes an interface to access the public key of the user’s authorization key and to request signatures using the authorization key.
Include the resulting authorization signature as a request header when making requests to the Privy API to modify resources owned by the user.