Fraud authentication tutorial¶
Safe walkthrough of the Fraud bidirectional ApiKey JWT contract.
Never commit private keys
Generate keys locally. Exchange public keys only through the channel MasteryHive security designates. The snippets below use ephemeral keys and example claims.
What you implement¶
| Direction | Who signs | Who verifies | Claims |
|---|---|---|---|
| Inbound (your backend → Fraud scoring) | Your backend private key | Fraud service (your public key configured there) | iss=software-service, aud=ai-service, exp unexpired |
| Outbound (Fraud → your backend) | AI private key | Your backend (AI public key) | iss=ai-service, aud=software-service, short exp (~5 minutes), sub = calling service name |
Algorithm: RS256 only.
Header scheme: Authorization: ApiKey <jwt> — the scheme word is ApiKey, not Bearer.
Also required: x-tenant-id on every scoring call.
Mint an inbound token (example)¶
# docs example — run locally; do not paste real production keys into tickets or git
import time
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import jwt # PyJWT
# Ephemeral demo keys (replace with your real key pair in each environment)
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
private_pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
public_pem = key.public_key().public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
now = int(time.time())
token = jwt.encode(
{
"iss": "software-service",
"aud": "ai-service",
"sub": "partner-backend",
"iat": now,
"exp": now + 300, # 5 minutes — keep short
},
private_pem,
algorithm="RS256",
)
# Call:
# Authorization: ApiKey <token>
# x-tenant-id: <your-tenant>
Decoded payload shape (illustrative):
{
"iss": "software-service",
"aud": "ai-service",
"sub": "partner-backend",
"iat": 1735680000,
"exp": 1735680300
}
Verify an outbound token (report callback)¶
When Fraud calls your POST …/transaction/create-report:
- Require
Authorizationstarting withApiKey. - Verify RS256 with the AI public key for that environment.
- Require
iss == "ai-service"andaud == "software-service". - Reject expired tokens.
- Read
x-tenant-idand bind the report to that tenant in your store.
claims = jwt.decode(
token,
ai_public_pem,
algorithms=["RS256"],
audience="software-service",
issuer="ai-service",
)
Key exchange and rotation¶
- Generate an RS256 key pair per environment (or per security policy).
- Send public keys to MasteryHive; receive the AI public key.
- Configure both sides before cutting traffic.
- Rotation: deploy new verify keys (accept old+new), switch signers, then remove old keys. Updating only one side causes mass 401s.
Common 401 causes¶
| Cause | Fix |
|---|---|
Missing Authorization |
Send header |
Bearer instead of ApiKey |
Change scheme word |
| Wrong private key / signature | Confirm key pair matches the environment |
Expired exp |
Mint a fresh token; shorten clock skew |
Wrong iss or aud |
Use exact strings above |
| AI outbound verify failing on your side | Install correct AI public key; check clock |
Missing x-tenant-id is 422, not 401.