Security Guidelines

Security Guidelines #

Transport Security #

Use HTTPS #

All webhook communication must occur over HTTPS. HTTP connections are not permitted.

TLS Requirements #

  • Minimum requirement: TLS 1.2+
  • Recommended: TLS 1.3 for optimal security

Token Security #

Implement Replay Protection #

// Example: JTI-based replay protection
const usedTokens = new Set();

function checkReplayProtection(jti) {
  if (usedTokens.has(jti)) {
    throw new Error('Token already used (replay attack)');
  }
  usedTokens.add(jti);
}

Validate Token Timing #

function validateTokenTiming(decoded, clockSkew = 60) {
  const now = Math.floor(Date.now() / 1000);

  // Apply clock skew tolerance
  if (decoded.exp <= (now - clockSkew)) {
    throw new Error('Token has expired');
  }

  if (decoded.nbf > (now + clockSkew)) {
    throw new Error('Token is not yet valid');
  }
}

Signature Algorithms #

  • Required: All tokens must be signed
  • Algorithm allowlist: Implementations MUST maintain an allowlist of approved algorithms
  • Reject “none”: Always reject tokens with algorithm “none”
  • Recommended algorithms: HS256, HS384, HS512 (HMAC variants) for balance of security and performance
  • Alternative algorithms: RS256, ES256 may be used when asymmetric cryptography is required

Validation Requirements #

All SWT tokens must be transmitted via HTTP POST. The validation workflow is:

1. Verify JWT signature and structure
2. Verify token type is SWT (typ: "SWT")
3. Validate standard claims (exp, nbf, iat, iss, jti)
4. Verify algorithm is on allowlist (reject "none")
5. Confirm webhook claim exists with event field
6. For non-empty request bodies:
   - Verify hash field exists in webhook claim
   - Compute hash of request body
   - Verify computed hash matches token hash value
7. For empty request bodies:
   - Verify hash field is absent from webhook claim
8. Perform replay protection (verify jti not used)

Best Practices #

Token Lifetime #

  • Short validity period: Typically no more than 15 minutes
  • Clock skew tolerance: Approximately 60 seconds for time validation
  • Minimum TLS version: TLS 1.2+ (TLS 1.3 recommended)

Replay Protection #

  • JTI tracking: Store already used token IDs
  • TTL-based cleanup: Automatically remove old JTIs
// Example: TTL-based JTI cleanup
class TokenReplayProtection {
  constructor() {
    this.usedTokens = new Map();
  }
  
  addToken(jti, expiration) {
    this.usedTokens.set(jti, expiration);
    this.cleanupExpiredTokens();
  }
  
  cleanupExpiredTokens() {
    const now = Date.now() / 1000;
    for (const [jti, exp] of this.usedTokens.entries()) {
      if (exp < now) {
        this.usedTokens.delete(jti);
      }
    }
  }
}

Monitoring and Logging #

  • Log failed validations
  • Monitor suspicious activities
  • Collect token usage statistics
// Example: Security logging
function logSecurityEvent(event, details) {
  console.log(JSON.stringify({
    timestamp: new Date().toISOString(),
    event: event,
    details: details,
    severity: event.includes('failed') ? 'HIGH' : 'INFO'
  }));
}