Skip to content

Latest commit

 

History

History
298 lines (225 loc) · 6.52 KB

File metadata and controls

298 lines (225 loc) · 6.52 KB

API Documentation

Overview

The ETIS Auth Provider exposes a simple REST API for exchanging iCal tokens for JWT tokens.

Base URL: http://localhost:8080 (default)

Authentication Flow

Client → POST /auth with iCal token → JWT token
Client → Use JWT for protected resources

Endpoints

POST /auth

Exchange a valid 16-character iCal token for a JWT token.

Request Methods:

  1. JSON Body:
POST /auth HTTP/1.1
Content-Type: application/json

{
  "token": "1234567890abcdef"
}
  1. Authorization Header:
POST /auth HTTP/1.1
Authorization: Bearer 1234567890abcdef

Success Response (200 OK):

{
  "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDcwNzIzMDAsImlhdCI6MTcwNzA2ODcwMCwic3ViIjoiYTY2NWExNDU5MjAxZDJkYzc4NTNjNWY4MzgxMWI0ZjEzZmE3YzhlNDNmZTdlZmM5MGQxNDNlYjE2ZTg4YmY0YiJ9.signature"
}

JWT Payload Structure:

{
  "sub": "a665a14592...",  // SHA256 hash of the iCal token
  "iat": 1707068700,        // Issued at (Unix timestamp)
  "exp": 1707072300         // Expiration (Unix timestamp)
}

Error Responses:

Status Code Error Description
400 {"error":"Token required"} No token provided in request
400 {"error":"Invalid JSON"} Malformed JSON body
401 {"error":"Invalid token"} Token validation failed (wrong length, format, or not found on upstream)
429 {"error":"Rate limit exceeded"} Too many requests
500 {"error":"Failed to generate token"} Internal server error during JWT generation
500 {"error":"Validation failed"} Unexpected error during validation
503 {"error":"Upstream service unavailable"} ETIS iCal service is not available (network error, timeout, server error)

Rate Limiting:

  • Global rate limit (default: 100 requests per 60 seconds)
  • Per-IP rate limit (default: 10 requests per 60 seconds per IP)

Example Request:

curl -X POST http://localhost:8080/auth \
  -H "Content-Type: application/json" \
  -d '{"token":"1234567890abcdef"}'

Example with Authorization Header:

curl -X POST http://localhost:8080/auth \
  -H "Authorization: Bearer 1234567890abcdef"

GET /jwk

JWK (JSON Web Key) endpoint for KrakenD JWT validation. Returns the public key information in JWK format for validating JWT tokens signed by this service.

Response (200 OK):

{
  "keys": [
    {
      "kty": "oct",
      "alg": "HS256",
      "k": "base64url-encoded-secret",
      "kid": "auto-generated-key-id"
    }
  ]
}

Example:

curl http://localhost:8080/jwk

Usage with KrakenD:

This endpoint should be configured in KrakenD's auth/validator section:

{
  "extra_config": {
    "auth/validator": {
      "alg": "HS256",
      "jwk_url": "http://etis-auth-provider:8080/jwk",
      "cache": true,
      "cache_duration": 3600,
      "disable_jwk_security": true
    }
  }
}

Notes:

  • The kid (Key ID) is automatically generated from the secret hash
  • KrakenD will cache the JWK response for the configured duration
  • disable_jwk_security: true is required for symmetric keys (HS256)
  • The same JWT_SECRET must be used in both services

GET /health

Health check endpoint for monitoring and liveness probes.

Response (200 OK):

{
  "status": "ok"
}

Example:

curl http://localhost:8080/health

GET /ready

Readiness check endpoint for Kubernetes readiness probes.

Response (200 OK):

{
  "status": "ok"
}

Example:

curl http://localhost:8080/ready

CORS Support

The service supports CORS for cross-origin requests:

  • Allowed Methods: GET, POST, OPTIONS
  • Allowed Headers: Authorization, Content-Type
  • Max Age: 86400 seconds (24 hours)

OPTIONS Preflight:

curl -X OPTIONS http://localhost:8080/auth \
  -H "Origin: https://example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: Authorization"

Error Handling

All errors follow this format:

{
  "error": "Error message"
}

Common HTTP status codes:

  • 200 - Success
  • 400 - Bad Request (client error)
  • 401 - Unauthorized (invalid token)
  • 405 - Method Not Allowed
  • 429 - Too Many Requests (rate limit exceeded)
  • 500 - Internal Server Error
  • 503 - Service Unavailable (upstream service unreachable)

Token Validation Rules

  1. Length: Token must be exactly 16 characters
  2. Format: Any alphanumeric characters
  3. Validation: Token is validated against upstream ETIS service (ical.psu.ru)
  4. Caching: Valid tokens are cached for the configured duration (default: 3600 seconds)

JWT Details

Signing Algorithm

  • Algorithm: HS256 (HMAC-SHA256)
  • Secret: Configured via JWT_SECRET environment variable

Claims

  • sub (Subject): SHA256 hash of the iCal token (64 hex characters)
  • iat (Issued At): Unix timestamp when JWT was issued
  • exp (Expiration): Unix timestamp when JWT expires (default: iat + 3600 seconds)

Verification

To verify JWT tokens in your application:

Go:

import "github.com/golang-jwt/jwt/v5"

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
    if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
        return nil, fmt.Errorf("unexpected signing method")
    }
    return []byte("your-jwt-secret"), nil
})

Node.js:

const jwt = require('jsonwebtoken');

jwt.verify(token, 'your-jwt-secret', (err, decoded) => {
  if (err) {
    console.error('Invalid token');
  } else {
    console.log(decoded.sub); // Token hash
  }
});

Python:

import jwt

try:
    payload = jwt.decode(token, 'your-jwt-secret', algorithms=['HS256'])
    print(payload['sub'])  # Token hash
except jwt.InvalidTokenError:
    print('Invalid token')

Security Considerations

  1. Always use HTTPS in production to protect tokens in transit
  2. Keep JWT_SECRET secure - use strong, randomly generated secrets
  3. Tokens are cached - revocation is not immediate (cache TTL applies)
  4. Rate limiting - protects against brute force attacks
  5. Token hash in JWT - original iCal token is never stored in JWT

Testing

See examples/test-requests.sh for comprehensive testing examples.

Quick test:

# Health check
curl http://localhost:8080/health

# Test auth (will fail with invalid token)
curl -X POST http://localhost:8080/auth \
  -H "Content-Type: application/json" \
  -d '{"token":"1234567890abcdef"}'