Overview
Request signing binds an API Key to a key pair you control. You keep the private key and register the public key on the API Key. Every request then carries a signature over its method, URL, API Key and body. Augustus verifies the signature with the registered public key. Augustus rejects a signed request that is sent again, or whose signed parts were changed. The signed parts are the method, the URL, the API Key, the body and the headers listed under Covered Components.- Signatures follow HTTP Message Signatures (RFC 9421).
- Request bodies are hashed with
Content-Digest(RFC 9530). - Supported keys are Ed25519 and ECDSA P-256 with SHA-256.
Set Up Request Signing
1
Generate a key pair
Create a P-256 key pair with OpenSSL:
signing-private.pem is the private key. Store it in your secrets manager. Never commit it and never send it to Augustus. signing-public.pem is the public key you register in the next step.Use Ed25519 instead
Use Ed25519 instead
Ed25519 needs OpenSSL 3. Run With OpenSSL 3 on your
openssl version to check. macOS ships LibreSSL, which cannot create Ed25519 keys. Install OpenSSL 3 with brew install openssl and call it by its full path:PATH, run the same commands with openssl.Private key format
Private key format
The SDK reads an unencrypted PKCS#8 PEM key, which starts with
-----BEGIN PRIVATE KEY-----. openssl genpkey writes this format. openssl ecparam -genkey writes a SEC1 key that starts with -----BEGIN EC PRIVATE KEY-----, which the SDK rejects. Convert one with openssl pkcs8 -topk8 -nocrypt -in ec-key.pem -out signing-private.pem.2
Register the public key
In the Augustus Dashboard, go to Developer > Secrets. If your account uses both APIs, open the 2023-01-01 tab. Under API keys, select Generate new. Paste the whole content of
signing-public.pem into Signing public key, including the BEGIN and END lines.You can add a public key only when you create the API Key. The key list then shows Request signing enabled and the Public key fingerprint of the API Key. Your signatures carry the fingerprint as keyid.3
Sign your requests
Use the SDK, or sign requests yourself with another HTTP client.
4
Test in sandbox
Augustus checks signatures only on API Keys with a public key. A request with any other key succeeds whether it is signed or not. Test both cases with the new sandbox key on
https://api.sand.getivy.de:- Send an unsigned request. Expect
401with the messageA request signature is required.A2xxmeans the key has no public key. - Send a signed request. Expect a
2xx. On a401, see Troubleshooting.
Move an Existing Integration to Signed Requests
You cannot add a public key to an existing API Key. Move to a new API Key that has one. Augustus ignores signatures on API Keys without a public key, so you can ship signing before you switch keys.- Generate a key pair and store the private key in your secrets manager.
- Deploy signing with your current API Key. Set
IVY_SIGNING_PRIVATE_KEYfor the SDK, or add the signature headers in your own client. Requests keep working, because the current key has no public key. - Create a new API Key with the public key. Give it the same IP allowlist as the current key.
- Test the new key in sandbox, as in the Test in sandbox step.
- Replace the current API Key with the new one in every service that uses it.
- Check that requests succeed, then revoke the old API Key.
Sign With the SDK
@getivy/node-sdk signs every request once it has the private key. It reads the key from IVY_SIGNING_PRIVATE_KEY:
\n, which breaks the key. In that case, pass the key with the signingPrivateKey option:
Sign Requests Yourself
Sign requests yourself in a language without an Augustus SDK, or with your own HTTP client. Any RFC 9421 library works if it produces the headers below.Headers
A signed request carries three headers next toX-Ivy-Api-Key:
The signature label is always
sig1.
Covered Components
Cover exactly this set. Augustus rejects a signature that leaves out a component or adds another one. Component parameters such as
;sf or ;req are not accepted.
Signature Parameters
Augustus rejects any other parameter, including
expires.
Signature Encoding
An Ed25519 signature is 64 bytes. A P-256 signature is the raw 64-byter || s value (IEEE P1363), not DER. In Node.js, pass dsaEncoding: 'ieee-p1363'. Encode the signature in standard base64.
Body Rules
- Send JSON bodies with
Content-Type: application/json. Acharsetparameter is allowed. - Do not compress the body. Augustus rejects a
Content-Encodingother thanidentity. - Hash the exact bytes you send. Serialize the body once and send that same string.
- Send each covered header once. Augustus rejects a request with two copies of a header.
Signature Base
The signer signs the signature base. It has one line per covered component, in the order ofSignature-Input, and ends with the @signature-params line. Lines are separated by \n, with no trailing line break.
Request:
Node.js Example
This module signs a request and sends it withfetch. It needs Node.js 18 or later and no dependencies. It reads the private key from IVY_SIGNING_PRIVATE_KEY and computes keyid from it.
signed-fetch.mjs
fetch. Pass the body as a string.
Retries
Sign every attempt again. A retry needs a newnonce and a current created, so a stored signature fails with nonce_reused or created_out_of_window. Keep the same Idempotency-Key on every attempt, so Augustus runs the operation once.
Sandbox and Production
Sandbox and production API Keys are separate, and signing is set on each API Key. Register a public key on every key you sign with, in both environments. Use a different key pair in each environment.Change the Key Pair
The public key of an API Key cannot change. Rotate in the dashboard keeps the key pair: it issues a new API Key with the same public key, and the old API Key keeps working for one day. To move to a new key pair, replace the API Key:- Generate a new key pair.
- Create a new API Key with the new public key.
- Deploy your integration with the new API Key and the new private key.
- Revoke the old API Key.
Troubleshooting
Augustus answers a request with a missing or invalid signature with401. The message is A request signature is required. when the Signature or Signature-Input header is missing. Otherwise it is Request signature is invalid: <reason>.
401 Invalid signature
When Augustus requires request signing for all API Keys, a request with an API Key that has no signing public key fails with
403 and the message This API key needs a registered signing public key. Create a new API Key with a signing public key.