|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Authorino is a Kubernetes-native authorization service that implements Envoy's external authorization gRPC protocol. It acts as an authorization layer between Envoy proxy and upstream services, providing hybrid API security with support for multiple authentication protocols (JWT/OIDC, API keys, mTLS, OAuth2 token introspection, Kubernetes TokenReview) and authorization mechanisms (pattern-matching, OPA/Rego, Kubernetes SubjectAccessReview, SpiceDB). |
| 8 | + |
| 9 | +## Essential Commands |
| 10 | + |
| 11 | +### Development Workflow |
| 12 | + |
| 13 | +```bash |
| 14 | +# Download dependencies |
| 15 | +make vendor |
| 16 | + |
| 17 | +# Run tests |
| 18 | +make test |
| 19 | + |
| 20 | +# Run benchmarks |
| 21 | +make benchmarks |
| 22 | + |
| 23 | +# Build the binary |
| 24 | +make build |
| 25 | + |
| 26 | +# Build Docker image |
| 27 | +make docker-build |
| 28 | + |
| 29 | +# Run linter |
| 30 | +make lint |
| 31 | + |
| 32 | +# Fix linting issues |
| 33 | +make lint-fix |
| 34 | +``` |
| 35 | + |
| 36 | +### Code Generation |
| 37 | + |
| 38 | +```bash |
| 39 | +# Generate deepcopy code for types |
| 40 | +make generate |
| 41 | + |
| 42 | +# Generate CRDs and RBAC manifests |
| 43 | +make manifests |
| 44 | +``` |
| 45 | + |
| 46 | +### Local Development with Kind |
| 47 | + |
| 48 | +```bash |
| 49 | +# Full local setup (cluster + deps + build + deploy + apps) |
| 50 | +make local-setup |
| 51 | + |
| 52 | +# Rebuild and redeploy after code changes |
| 53 | +make local-rollout |
| 54 | + |
| 55 | +# Delete local cluster |
| 56 | +make local-cleanup |
| 57 | + |
| 58 | +# Port forward to Envoy for testing |
| 59 | +kubectl port-forward deployment/envoy 8000:8000 |
| 60 | +``` |
| 61 | + |
| 62 | +### Running Single Tests |
| 63 | + |
| 64 | +```bash |
| 65 | +# Run specific test |
| 66 | +go test ./pkg/auth -run TestSpecificFunction |
| 67 | + |
| 68 | +# Run with verbose output |
| 69 | +go test -v ./pkg/evaluators/... |
| 70 | + |
| 71 | +# Run with race detection |
| 72 | +go test -race ./... |
| 73 | +``` |
| 74 | + |
| 75 | +## Architecture |
| 76 | + |
| 77 | +### Core Components |
| 78 | + |
| 79 | +**Auth Pipeline**: Authorino processes requests through a 5-phase pipeline: |
| 80 | +1. **Authentication** (phase i): Verify identity from credentials (at least one must succeed) |
| 81 | +2. **Metadata** (phase ii): Fetch external data to enrich context |
| 82 | +3. **Authorization** (phase iii): Evaluate policies (all must pass) |
| 83 | +4. **Response** (phase iv): Build dynamic responses (headers, wristbands, dynamic metadata) |
| 84 | +5. **Callbacks** (phase v): Send HTTP callbacks |
| 85 | + |
| 86 | +**Index**: In-memory data structure that maps hosts to AuthConfig specs. Built and reconciled by watching AuthConfig and Secret resources. |
| 87 | + |
| 88 | +**Authorization JSON**: Working memory for each request containing `context` (request data from Envoy) and `auth` (resolved identity, metadata, authorization results). Evaluators read/write from this structure. |
| 89 | + |
| 90 | +### Key Packages |
| 91 | + |
| 92 | +- `api/v1beta2` & `api/v1beta3`: AuthConfig CRD definitions |
| 93 | +- `controllers/`: Kubernetes controllers for AuthConfig and Secret reconciliation |
| 94 | +- `pkg/service/`: gRPC and HTTP authorization service implementations |
| 95 | +- `pkg/auth/`: Core authentication logic and credential extraction |
| 96 | +- `pkg/evaluators/`: Implementations of auth pipeline phases: |
| 97 | + - `evaluators/identity/`: Authentication evaluators (JWT, API key, OAuth2, etc.) |
| 98 | + - `evaluators/authorization/`: Authorization evaluators (OPA, pattern-matching, K8s SAR, etc.) |
| 99 | + - `evaluators/metadata/`: External metadata fetchers (HTTP, OIDC UserInfo, UMA) |
| 100 | + - `evaluators/response/`: Dynamic response builders (wristbands, JSON injection) |
| 101 | +- `pkg/index/`: AuthConfig index management |
| 102 | +- `pkg/metrics/`: Prometheus metrics |
| 103 | +- `pkg/trace/`: OpenTelemetry tracing |
| 104 | + |
| 105 | +### Main Entry Point |
| 106 | + |
| 107 | +`main.go` defines a Cobra CLI with three commands: |
| 108 | +- `authorino server`: Runs the authorization server (primary mode) |
| 109 | +- `authorino webhooks`: Runs validation webhooks |
| 110 | +- `authorino version`: Prints version info |
| 111 | + |
| 112 | +The server command starts: |
| 113 | +- gRPC auth service (port 50051, implements Envoy external auth protocol) |
| 114 | +- HTTP auth service (port 5001, raw HTTP interface) |
| 115 | +- OIDC server (port 8083, for Festival Wristband token discovery) |
| 116 | +- Kubernetes reconciliation managers (AuthConfig & Secret controllers) |
| 117 | + |
| 118 | +## AuthConfig Custom Resource |
| 119 | + |
| 120 | +AuthConfigs declare the protection rules for services. Key sections: |
| 121 | + |
| 122 | +```yaml |
| 123 | +spec: |
| 124 | + hosts: [] # Host names this config applies to |
| 125 | + when: [] # Top-level conditions |
| 126 | + authentication: {} # Identity verification (required, 1+ configs) |
| 127 | + metadata: {} # External data fetching (optional) |
| 128 | + authorization: {} # Policy enforcement (optional) |
| 129 | + response: # Dynamic responses (optional) |
| 130 | + success: |
| 131 | + headers: {} # HTTP headers to inject |
| 132 | + dynamicMetadata: {} # Envoy dynamic metadata |
| 133 | + callbacks: {} # HTTP callbacks (optional) |
| 134 | +``` |
| 135 | +
|
| 136 | +## Working with the Codebase |
| 137 | +
|
| 138 | +### Host Lookup |
| 139 | +
|
| 140 | +Authorino reads `Attributes.Http.Host` from Envoy's CheckRequest or `host` from `ContextExtensions`. It supports: |
| 141 | +- Exact host matching |
| 142 | +- Wildcard subdomain matching (e.g., `*.pets.com`) |
| 143 | +- Host collision prevention (can be disabled with `--allow-superseding-host-subsets`) |
| 144 | + |
| 145 | +### Reconciliation & Status Updates |
| 146 | + |
| 147 | +- All replicas reconcile the same resources matching `--auth-config-label-selector` and `--secret-label-selector` |
| 148 | +- One replica is elected leader for status updates |
| 149 | +- The index is updated when AuthConfigs or related Secrets change |
| 150 | + |
| 151 | +### Common Development Patterns |
| 152 | + |
| 153 | +**Adding a new evaluator**: |
| 154 | +1. Implement the evaluator interface in the appropriate `pkg/evaluators/` subdirectory |
| 155 | +2. Add CRD spec in `api/v1beta3/auth_config_types.go` |
| 156 | +3. Update controller reconciliation logic in `controllers/auth_config_controller.go` |
| 157 | +4. Add tests following existing patterns in the evaluator's package |
| 158 | + |
| 159 | +**Caching**: |
| 160 | +- OIDC/UMA configs are cached at reconciliation-time |
| 161 | +- JWKs are cached and auto-refreshed based on `spec.authentication.jwt.ttl` |
| 162 | +- Rego policies are precompiled at reconciliation-time |
| 163 | +- Each evaluator can use `spec..cache` for instance-level caching |
| 164 | + |
| 165 | +### Testing |
| 166 | + |
| 167 | +Tests use envtest (Kubernetes control plane components) for controller tests. Set `KUBEBUILDER_ASSETS` to the envtest binaries path (handled by `make test`). |
| 168 | + |
| 169 | +Mock generation example: |
| 170 | +```bash |
| 171 | +./bin/mockgen -source=pkg/auth/auth.go -destination=pkg/auth/mocks/mock_auth.go |
| 172 | +``` |
| 173 | + |
| 174 | +### Logging |
| 175 | + |
| 176 | +- Use structured logging via `logr.Logger` |
| 177 | +- Sensitive data must be redacted or logged at debug level (`V(1)`) |
| 178 | +- Include trace IDs for request correlation |
| 179 | + |
| 180 | +### Important Configuration Flags |
| 181 | + |
| 182 | +Server command flags: |
| 183 | +- `--watch-namespace`: Limit to specific namespace (cluster-wide if empty) |
| 184 | +- `--auth-config-label-selector`: Filter AuthConfigs by labels (sharding) |
| 185 | +- `--secret-label-selector`: Filter Secrets (default: `authorino.kuadrant.io/managed-by=authorino`) |
| 186 | +- `--timeout`: Server timeout in milliseconds |
| 187 | +- `--ext-auth-grpc-port`: gRPC service port (default: 50051) |
| 188 | +- `--ext-auth-http-port`: HTTP service port (default: 5001) |
| 189 | +- `--evaluator-cache-size`: Cache size per evaluator in MB |
| 190 | +- `--deep-metrics-enabled`: Enable detailed per-evaluator metrics |
| 191 | + |
| 192 | +## API Versions |
| 193 | + |
| 194 | +The project maintains two API versions: |
| 195 | +- `v1beta2`: Legacy version (in `api/v1beta2/`) |
| 196 | +- `v1beta3`: Current version (in `api/v1beta3/`) |
| 197 | + |
| 198 | +Both are registered in the scheme and controllers handle both versions. |
| 199 | + |
| 200 | +## Dependencies |
| 201 | + |
| 202 | +Built with: |
| 203 | +- Go 1.24.6 |
| 204 | +- controller-runtime v0.16.3 |
| 205 | +- Kubernetes client-go v0.28.3 |
| 206 | +- Envoy go-control-plane v1.32.4 |
| 207 | +- OPA v1.4.0 |
| 208 | +- CEL (Common Expression Language) for dynamic expressions |
0 commit comments