Skip to content

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:

  1. Require Authorization starting with ApiKey.
  2. Verify RS256 with the AI public key for that environment.
  3. Require iss == "ai-service" and aud == "software-service".
  4. Reject expired tokens.
  5. Read x-tenant-id and 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

  1. Generate an RS256 key pair per environment (or per security policy).
  2. Send public keys to MasteryHive; receive the AI public key.
  3. Configure both sides before cutting traffic.
  4. 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.