Transport & Message Security
How APT Commerce protects API traffic in transit, how we manage edge certificates, and how you opt into message-level encryption (MLE) for sensitive requests and responses.
Supported protocols & ciphers
All APT endpoints (api.aptcommerce.com, sandbox, dashboard, and webhook delivery from APT) require modern TLS. Plaintext HTTP is rejected with 426 Upgrade Required.
| Protocol | Status | Notes |
|---|---|---|
TLS 1.3 | Preferred | Negotiated by default for all modern clients. |
TLS 1.2 | Required minimum | AEAD cipher suites only. |
TLS 1.1 / 1.0 | Disabled | Removed 2024-01-31. Connections are rejected at the edge. |
SSLv3 / SSLv2 | Disabled | Never supported. |
Cipher suite policy follows the industry-standard AEAD baseline: AES-128-GCM, AES-256-GCM, and ChaCha20-Poly1305 with ECDHE key exchange. CBC and RC4 suites are disabled. The active policy ID is exposed in the X-APT-TLS-Policyresponse header and changes are announced via the cipher-policy webhook (see below).
Detecting your client's TLS version
Before going live, verify your runtime negotiates TLS 1.2 or 1.3. Use one of:
# curl — force a floor and observe the negotiated version
curl -v --tlsv1.2 --tls-max 1.3 https://api.aptcommerce.com/v1/health 2>&1 | grep -i "SSL connection"
# openssl — inspect the handshake directly
openssl s_client -connect api.aptcommerce.com:443 -tls1_2 < /dev/null | grep -E "Protocol|Cipher"
# Node — enforce TLS 1.2 floor on outbound clients
const https = require('https');
const agent = new https.Agent({ minVersion: 'TLSv1.2' });
# Python — print the OpenSSL build powering your runtime
python -c "import ssl; print(ssl.OPENSSL_VERSION)"Keep your build on the latest supported stack
APT's policy is to always be one TLS major behind current best practice for the minimum, and always at current best for the preferred. To stay aligned:
- Pin your CI base image to an actively-maintained Node LTS or Python 3.11+ — older runtimes ship OpenSSL builds that may lose TLS 1.3 support.
- Enable Renovate or Dependabot on your APT SDK (
@aptcommerce/sdk) so security patches arrive automatically. - Add a CI guard that fails the build if your default TLS floor drops below 1.2:
# Node CI gate (add to a smoke-test step)
node -e "const tls=require('tls'); if (tls.DEFAULT_MIN_VERSION !== 'TLSv1.2' && tls.DEFAULT_MIN_VERSION !== 'TLSv1.3') { process.exit(1); }"We publish a weekly probe endpoint at https://tls-check.aptcommerce.comthat returns the negotiated protocol and cipher — schedule a synthetic check against it from your monitoring stack to catch regressions in your TLS posture.
Certificate management
APT's edge certificates are issued by a public CA (currently Let's Encrypt and Google Trust Services for redundancy) and rotated automatically on a 60–90 day cycle. You do not need to take action for routine rotation.
Fetch the current SPKI fingerprint:
openssl s_client -servername api.aptcommerce.com -connect api.aptcommerce.com:443 \ -showcerts < /dev/null 2>/dev/null \ | openssl x509 -pubkey -noout \ | openssl pkey -pubin -outform der \ | openssl dgst -sha256 -binary | openssl enc -base64
The published rotation calendar lives at https://trust.aptcommerce.com/calendar.ics and the active fingerprints (leaf + issuing CAs) are served as JSON at /v1/trust/fingerprints. Both surfaces also emit the certificate.rotated webhook when a rotation lands.
Message-level encryption (MLE)
MLE wraps the entire request and response body for endpoints that carry sensitive data — PANs, full bank account numbers, full Tax IDs, stablecoin custody keys — in a JWE envelope (RFC 7516) on top of TLS. This protects payloads from intermediate logging, in-memory dumps, and TLS-terminating proxies inside your own infrastructure.
Status: Optional today, available in sandbox and production. MLE will become required for new sensitive-data endpoints in a future release; we will publish a 12-month deprecation timeline before any existing endpoint is flipped to MLE-required.
Quickstart
- Fetch APT's public key for your merchant:
GET /v1/mle/keys/current. The response includes thekid, algorithm (RSA-OAEP-256), and content encryption (A256GCM). - Encrypt your request body as a compact JWE using that key.
- Send the JWE as the request body with headers
Content-Type: application/joseandX-APT-MLE: v1. - If you sent
X-APT-MLE-Response: required, the response body is a JWE encrypted to a public key you registered at/v1/mle/keys/customer.
# Plain request body (what you encrypt)
{ "amount": 5000, "currency": "usd", "card": { "number": "4111...", "cvv": "123", "exp_month": 12, "exp_year": 2028 } }
# What goes on the wire
POST /v1/transactions
Authorization: Bearer sk_live_...
Content-Type: application/jose
X-APT-MLE: v1
X-APT-MLE-Response: required
eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoibWxlX2tleV8wMUhXIn0.
<encrypted_key>.<iv>.<ciphertext>.<tag>Key rotation
APT MLE keys rotate every 90 days. Always look up the current kidat request time rather than caching for more than 24 hours. The mle.key.rotated webhook fires when a new key becomes current; the previous key remains valid for decryption for 30 days.
Error codes
| Code | HTTP | Meaning |
|---|---|---|
mle_required | 400 | Endpoint requires MLE but request was plaintext. |
mle_kid_unknown | 400 | kid not recognized — refetch the current key. |
mle_kid_expired | 400 | Key rotated more than 30 days ago. |
mle_decrypt_failed | 400 | JWE could not be decrypted with the named key. |
mle_response_key_missing | 400 | Requested encrypted response but no customer public key on file. |
Change notifications
Subscribe to these webhooks (or poll the equivalent endpoints) to keep your integration aligned with APT's evolving security posture without manual monitoring:
| Event | Polling endpoint | Notice window |
|---|---|---|
tls.cipher_policy.changed | /v1/trust/tls-policy | ≥90 days before enforcement |
tls.protocol.deprecated | /v1/trust/tls-policy | 12 months before sunset |
certificate.rotated | /v1/trust/fingerprints | Emitted on rotation |
mle.key.rotated | /v1/mle/keys/current | Emitted on rotation |
mle.policy.changed | /v1/mle/policy | ≥12 months before MLE becomes required for an endpoint |
All notice windows are also posted to Changelog and the security advisory list at [email protected].
Related
- Authentication — API keys, idempotency, and step-up auth.
- Webhooks — signature verification and delivery retries.
- SDKs & libraries — minimum supported versions.
- Security baseline (operator guide) — operational checklist for your team.