JWS Signed Request Authentication
This authentication method provides request-level security using digital signatures, ensuring both authenticity and integrity of each HTTP request.
Unlike JWT authentication, where a token is sent, this method signs each request individually using a cryptographic signature.
Overview
In this model:
- The client signs each HTTP request using a private key
- The server verifies the signature using the corresponding public key
- The signature covers multiple parts of the HTTP request
- The signature is sent in an HTTP header (not in the body)
Key Concepts
Digital Signature
- Uses an RSA key pair (private/public)
- Client signs with private key
- Server verifies with public key
Key ID (kid)
- Each key pair has a unique identifier assigned by InComm
- The client must include this ID in the JWS header
- Used by the server to identify which key to use for verification
HTTP Headers
Every signed request must include:
- Authorization: INCOMM-OLS-EAPI-SIGNATURE-JWS
- Signature:
What Is Signed
The signature is computed over multiple parts of the HTTP request:
- HTTP method (e.g., POST)
- HTTP path (e.g., /v0/payments/closed-loop/sale)
- HTTP query string (normalized, including ?)
- HTTP body (JSON payload or empty string)
JWS Structure
This implementation uses JWS with detached payload:
- The payload (HTTP body) is NOT included inside the JWS
- The JWS is sent in the Signature header
- The body remains unchanged
JOSE Header Fields
Required:
- alg → PS512
- kid → Key ID assigned by InComm
- http-method → HTTP method
- http-path → Request path
- http-query → Query string
- crit → List of critical headers
Optional:
- iat → Issued at (epoch seconds)
- exp → Expiration time (epoch seconds)
Signing Algorithm
- Algorithm: PS512 (RSA-PSS with SHA-512)
- Key size: ≥ 3072 bits
How the Signature Is Built
- Build the JWS header with required fields
- Convert HTTP body to payload using BASE64URL(UTF8(body))
- Sign using private key
- Serialize JWS (compact format)
- Remove payload to create detached JWS
- Send in headers
Example
Request:
POST /v0/payments/closed-loop/sale
Headers:
Authorization: INCOMM-OLS-EAPI-SIGNATURE-JWS
Signature:
Body:
{
"amount": "100",
"currency": "USD"
}
Expiration Rules
- If exp is present → request must be before expiration
- If only iat is present → server may apply default expiration
- If neither is present → no expiration (not recommended)
Key Management
Key Onboarding
- Generate RSA key pair (≥ 3072 bits)
- Share public key (X.509 certificate)
- Receive key ID (kid)
- Key stored securely by InComm
Key Rotation
- Recommended at least once per year
- Maximum lifetime: 3 years
- New keys require onboarding
- Old keys are removed when no longer used
Security Benefits
- Ensures request integrity
- Ensures caller authenticity
- Prevents replay attacks (with exp / iat)
- No session tokens required
Best Practices
- Always include exp
- Rotate keys regularly
- Protect private keys securely
- Validate all request components
- Keep system clocks synchronized
Summary
This method signs each HTTP request individually using JWS detached signatures, providing strong security guarantees and suitability for high-trust integrations.