Authentication
Audience: Programmer
Overview
pyck uses ZITADEL for authentication and authorization. This document explains how to implement authentication when integrating with the pyck backend API.
Authentication Flow
Authentication is handled via JWT tokens or Personal Access Tokens (PATs)
The authentication middleware validates these tokens against ZITADEL
User information, including roles and tenant information, is extracted and added to the request context
Authentication Methods
JWT Authentication
Standard OpenID Connect flow using JWT tokens
Tokens are validated against ZITADEL's JWKS endpoint
Token validation includes signature verification and claims validation
Personal Access Token (PAT) Authentication
Alternative authentication method using long-lived tokens
PATs are introspected against ZITADEL's token introspection endpoint
Results are cached to improve performance
Authorization
Roles and Permissions
The backend supports the following roles with increasing privilege levels:
Reader (1000): Read-only access
Writer (1001): Read and write access
Admin (1002): Administrative access
System (1003): System-level access
Tenant Isolation
Users are associated with a tenant (organization)
Tenant ID can be specified via HTTP headers during authentication
Authentication ensures users can only access resources within their tenant
Implementation Details
Authentication Header
All authenticated requests require:
Authorization: Bearer <token>Where
<token>is either a valid JWT or PAT
Error Handling
HTTP Error Response Format
All HTTP endpoints (including authentication, health checks, webhooks, and file handlers) return errors in a standardized JSON format:
This applies to all non-GraphQL HTTP endpoints. For GraphQL-specific error handling, see the GraphQL Error Handling documentation.
Authentication Errors
Authentication errors return HTTP 401 Unauthorized status codes
All error responses follow the JSON format shown above
Common errors include expired tokens, invalid signatures, or insufficient permissions
Example authentication error response:
Unauthenticated Endpoints
Certain endpoints don't require authentication:
Health check endpoints (
/health)Metrics endpoints (
/metrics)Webhook endpoints (paths containing
/webhook/)Company registration GraphQL mutation
Tenant registration GraphQL mutation (registerTenant)
Frontend Configuration Discovery
pyck provides a /static/settings.json endpoint that frontends can use to discover OIDC runtime configuration dynamically, eliminating the need to hardcode environment-specific values.
Endpoint
Response Format
Usage
Frontend applications should fetch this endpoint at startup to configure their OIDC client and other runtime settings. This approach ensures configuration values remain consistent across environments without requiring separate build artifacts.
Example:
Development Guide
When developing against the pyck API, you'll need to:
Obtain a valid token from ZITADEL
Include this token in the Authorization header of all API requests
Implement token refresh logic when tokens expire
Handle authentication errors appropriately in your client application
Testing Authentication
For testing purposes, you can:
Use the ZITADEL developer console to generate test tokens
Verify token validity using the introspection endpoint
Test different roles to ensure proper authorization behavior
Tenant Registration Email Behavior
When using the registerTenant mutation, the system allows re-use of the same admin email address across multiple tenant registrations. Each tenant receives a unique tenant-specific primary email (e.g., user@tenant1.example.com, user@tenant2.example.com), with the original email added as an alias.
Important: Cross-tenant authorization is not supported. A user created for one tenant cannot access another tenant's resources, even if they share the same email alias.
Recommendation: Use unique email addresses for each tenant registration to avoid confusion and ensure clear account separation.
For detailed information, see the registerTenant mutation documentation.
Last updated
Was this helpful?
