@@ -8,7 +8,23 @@ This is a Kubernetes controller that reconciles Developer Portal capabilities ba
88
99** Domain** : kuadrant.io
1010** API Group** : devportal.kuadrant.io
11- ** Primary Resource** : APIProduct (v1alpha1)
11+ ** Resources (v1alpha1)** :
12+ - ` APIProduct ` : Represents an API offering in the developer portal
13+ - ` APIKey ` : Represents a developer's request for API access (created in consumer namespace)
14+ - ` APIKeyRequest ` : Shadow resource for RBAC-based request review (created in owner namespace)
15+ - ` APIKeyApproval ` : API owner's decision to approve/deny access requests
16+
17+ ## Design Documents
18+
19+ ** RBAC Design** : The project implements namespace-based RBAC for API management. Read the full design at:
20+ https://github.com/Kuadrant/kuadrant-console-plugin/blob/main/docs/designs/2026-03-26-api-management-rbac-design.md
21+
22+ Key concepts from the design:
23+ - ** Namespace isolation** : Consumers create APIKeys in their namespace, owners review APIKeyRequests in their namespace
24+ - ** Shadow resources** : APIKeyRequest mirrors APIKey in owner's namespace for RBAC-enforced discovery
25+ - ** Cross-namespace references** : APIKey references APIProduct across namespaces; APIKeyApproval references APIKey across namespaces
26+ - ** Secret projection** : API key values projected to status field, eliminating need for secret read permissions
27+ - ** Conditions pattern** : Uses conditions array (Pending/Approved/Denied/Failed) following CertificateSigningRequest pattern
1228
1329## Development Commands
1430
@@ -47,25 +63,33 @@ make install # Install CRDs to cluster
4763make deploy # Deploy controller to cluster
4864make uninstall # Remove CRDs from cluster
4965make undeploy # Remove controller from cluster
66+ make local-deploy # Deploy controller from current code
5067```
5168
52- ### Bundle Operations (Operator Lifecycle Manager)
69+ ### Build Utilities
5370``` bash
54- make bundle # Generate bundle manifests
55- make bundle-build # Build bundle image
71+ make build-installer # Generate consolidated YAML with CRDs and deployment
72+ make gateway-api-crds # Download Gateway API CRDs for testing
73+ make setup-test-e2e # Set up Kind cluster for e2e tests if it doesn't exist
74+ make cleanup-test-e2e # Tear down the Kind cluster used for e2e tests
5675```
5776
5877## Architecture
5978
6079### Project Structure
6180- ** api/v1alpha1/** : Kubernetes API definitions
6281 - ` apiproduct_types.go ` : APIProduct CRD schema (Spec, Status, and List types)
82+ - ` apikey_types.go ` : APIKey CRD schema for consumer access requests
83+ - ` apikeyrequest_types.go ` : APIKeyRequest CRD schema for owner-side request review
84+ - ` apikeyapproval_types.go ` : APIKeyApproval CRD schema for approval decisions
6385 - ` groupversion_info.go ` : API group registration
6486 - ` zz_generated.deepcopy.go ` : Auto-generated DeepCopy methods
6587
6688- ** internal/controller/** : Reconciliation logic
67- - ` apiproduct_controller.go ` : APIProductReconciler with Reconcile loop
68- - Controller uses client.Client for K8s API access
89+ - ` apiproduct_controller.go ` : APIProductReconciler for API product lifecycle
90+ - ` apikey_controller.go ` : APIKeyReconciler for consumer API key requests
91+ - ` apikeyrequest_controller.go ` : APIKeyRequestReconciler for request processing
92+ - Controllers use client.Client for K8s API access
6993 - RBAC permissions defined via kubebuilder markers (` +kubebuilder:rbac ` )
7094
7195- ** cmd/main.go** : Operator entry point
@@ -84,12 +108,30 @@ make bundle-build # Build bundle image
84108 - ` config/prometheus/ ` : Prometheus ServiceMonitor
85109
86110### Controller Pattern
87- The operator follows the standard Kubernetes controller pattern:
88- 1 . Watch APIProduct resources
89- 2 . Reconcile loop called on create/update/delete events
90- 3 . Compare desired state (Spec) vs actual state
91- 4 . Take actions to converge actual state to desired state
92- 5 . Update Status to reflect observed state
111+ The operator follows the standard Kubernetes controller pattern with multiple reconcilers:
112+
113+ ** APIProductReconciler** :
114+ 1 . Watches APIProduct resources
115+ 2 . Discovers associated PlanPolicy and AuthPolicy from HTTPRoute
116+ 3 . Fetches and stores OpenAPI spec
117+ 4 . Updates status with discovered plans and auth scheme
118+
119+ ** APIKeyReconciler** :
120+ 1 . Watches APIKey resources (consumer namespace)
121+ 2 . Creates APIKeyRequest shadow resource in owner namespace
122+ 3 . Processes APIKeyApproval decisions
123+ 4 . Creates API key secrets and projects values to status
124+ 5 . Updates conditions (Pending/Approved/Denied)
125+
126+ ** APIKeyRequestReconciler** :
127+ 1 . Watches APIKeyRequest resources (owner namespace)
128+ 2 . Handles automatic approval mode
129+ 3 . Syncs status with related APIKey
130+
131+ All controllers:
132+ - Compare desired state (Spec) vs actual state
133+ - Take actions to converge actual state to desired state
134+ - Update Status to reflect observed state
93135
94136### Key Dependencies
95137- ** controller-runtime v0.21.0** : Core controller framework
@@ -100,12 +142,22 @@ The operator follows the standard Kubernetes controller pattern:
100142## Important Notes
101143
102144### Modifying APIs
103- 1 . Edit types in ` api/v1alpha1/apiproduct_types .go `
145+ 1 . Edit types in ` api/v1alpha1/*_types .go `
1041462 . Run ` make manifests generate ` to regenerate code and CRDs
105- 3 . The APIProduct CRD currently has a placeholder ` Foo ` field - this should be replaced with actual fields
106-
107- ### Controller Implementation
108- The reconciler in ` internal/controller/apiproduct_controller.go ` is scaffolded but not implemented. The Reconcile function needs business logic added.
147+ 3 . Update RBAC role definitions in ` config/rbac/ ` if new permissions are needed
148+ 4 . Update sample manifests in ` config/samples/ ` to reflect new fields
149+
150+ ### RBAC Architecture
151+ The project implements namespace-based RBAC with three personas:
152+ - ** API Consumer** : Creates APIKey in their namespace, can read their own APIKey status
153+ - ** API Owner** : Views APIKeyRequest in their namespace, creates APIKeyApproval decisions
154+ - ** API Admin** : Manages APIProduct resources and overall API catalog
155+
156+ Critical security invariants:
157+ - Consumers CANNOT see other consumers' APIKeys (namespace isolation)
158+ - Owners CANNOT see APIKey secrets (shadow resource pattern)
159+ - APIKeyApproval namespace MUST match APIProduct namespace (validated by controller)
160+ - API key values projected to status field (no secret read permissions required)
109161
110162### Testing Environment
111163- E2e tests use Kind cluster named ` developer-portal-controller-test-e2e `
0 commit comments