core

Security & PDPA

Security standards — encryption at rest, HMAC webhooks, key management, data-subject rights under PDPA

⏱ PDPA

SlipBolt handles financial data, so security is designed in from the credential layer all the way to PDPA-compliant deletion

Authentication

CredentialUsed forDetails
JWT (HS256)Dashboard / LIFF15-minute access token + 7-day refresh (rotated) · cookie httpOnly + Secure + SameSite=Lax + path /api
API keyServer-to-serversk_live_… / sk_test_… · stored as an argon2 hash (shown in full once) · revoke/rotate yourself
  • Refresh tokens are stored as a sha256 hash (Session.tokenHash) — a leaked DB dump cannot be replayed
  • Refresh-reuse detection — an old token used again → the whole chain is revoked immediately
  • New-device detection — a login from a new device → email alert

Encryption

  • In transit: TLS 1.2+ on every endpoint
  • At rest: LINE channel secret/token encrypted with AES-256-GCM (key ENCRYPTION_KEY · 32-byte hex) — decrypted only when calling the LINE API, plaintext is never cached in Redis
  • User passwords: argon2id

Webhook integrity

  • Inbound (LINE): the HMAC-SHA256 of the raw body is checked on every request before it is accepted
  • Outbound (yours): every delivery is signed X-Slipbolt-Signature: t=<ts>,v1=<hmac> — verify it every time with the endpoint's webhook secret (see Webhooks)

Rate limit & abuse

  • Global throttle 120 req/min · login 5 req/min
  • API keys have a per-key rate limit of 120 req/min (same on every plan · not tied to price)
    • a combined ceiling of 240 req/min on POST /api/v1/verify — see Authentication
  • Input to POST /api/v1/verify: raw bytes · multipart/form-data · JSON image (base64) / url / qr — the whole request is capped at 5 MB · url must be public https:// (the real IP is checked after DNS resolution — internal/cloud-metadata addresses are refused) and redirects are not followed

Audit log

Every security event (login/logout · password · session · link/unlink · API key · plan · admin action) is stored in audit_logs, append-only · users can see their own at Settings → Audit Log · pruned automatically after 90 days

System logs redact sensitive values automatically (password, *token*, *secret*, Authorization)

PDPA — data-subject rights

RightWhere
Access / PortabilityGET /auth/me/export → all your data as JSON (no secrets) · Settings → Security
ErasureDELETE /auth/me → soft-delete + cancel subscription + revoke every session · hard-deleted by cron after 24 hours
Slip privacySlip images are discarded right after verification (never persisted) · only text is kept (ref/amount/date/name)
RetentionTransaction data is anonymised automatically after pdpaRetentionMonths (default 12 months) when the shop enables auto-delete

Every piece of data is isolated per shop (shopId) — nothing leaks across tenants

Reporting a vulnerability

Found a security issue? Please contact the team before disclosing it publicly — we will respond and fix it promptly