Skip to main content

JWT authentication

To securely authenticate API requests, Bastion supports JWT-based request signing using ES256 public keys. This guide walks you through setting up your API key for JWT authentication and how to include signed tokens in your API requests.

Step 1: Upload a public key

To enable JWT authentication for your API key:
  1. Generate an ES256 (P-256 curve, SHA-256) public/private key pair.
  2. Go to your Bastion Dashboard, find the relevant API key, and select Add public key.
  3. In the pop-up, paste your ES256 public key in PEM format and select Add public key.
Important: Once a public key is associated with an API key, all requests using that key must include a valid JWT. Requests without a properly signed token will be rejected.

Step 2: Sign requests with a JWT

Each request must include an ES256-signed JWT in the request headers. The token must include the following claims:
  • iat – A Unix timestamp representing the time of the request.
    • Must be valid within 30 seconds of the server time.
    • Cannot be in the future.
  • req-path – The full request path and query parameters (e.g. /v2/crypto/deposits?account_id=123).
  • req-method – The HTTP method used (e.g. POST, PUT, GET, etc.).
  • body – The request body, if applicable.
    • You may omit this claim for GET or HEAD requests.
    • Ensure the request body is serialized in the exact order it is transmitted, then hashed with SHA-256 and hex-encoded.
For a working example, see JWT generation example.

Example claims

Step 3: Send the JWT in headers

Include the signed JWT in the bastion-signature header:
Here’s an example using curl:
💡 Replace <your-signed-jwt> with the actual ES256 JWT, signed using your private key.

Conclusion

Once your API key is configured with a public key, JWTs must be used for all future requests. This approach enhances the security of your API interactions and ensures all requests are verifiably authentic. If you have questions about key generation, JWT formatting, or encounter issues, feel free to contact us at try@bastion.io. We’re here to help!