You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: refactor authentication flows inside of the webhook (#225)
* Refactor authentication flow in the webhook.
Remove the obsolete long-live token authentication option.
Add the possibility to setup multitenant environment using SA keys per namespace.
Add the possibility to use WIF auth flow.
* Add integration test for the multitenant auth flow.
* Update documentation
* fix: code review
* fix: lint and lower acme record default TTL
Facilitate a webhook integration for leveraging the STACKIT DNS alongside
13
-
its [API](https://docs.api.stackit.cloud/documentation/dns/version/v1) to act as a DNS01
14
-
ACME Issuer with [cert-manager](https://cert-manager.io/docs/).
12
+
Facilitate a webhook integration for leveraging the STACKIT DNS alongside its [API](https://docs.api.stackit.cloud/documentation/dns/version/v1) to act as a DNS01 ACME Issuer with [cert-manager](https://cert-manager.io/docs/).
The STACKIT webhook requires authentication against the STACKIT DNS API. Depending on your cluster architecture and security policies, you can authenticate using one of the three methods below.
24
+
25
+
The webhook will explicitly fail if multiple mutually exclusive authentication methods are configured for a single Issuer.
26
+
27
+
### Option A: Dynamic Service Account Key (Multi-Tenant)
28
+
29
+
This method is recommended for multi-tenant clusters where different `Issuer` or `ClusterIssuer` resources manage zones across different STACKIT projects. The webhook fetches the Service Account JSON directly from a Kubernetes Secret per challenge.
Ensure the `serviceAccountSecretNamespace` matches the namespace of your Secret. If you want the webhook to read secrets outside of its own installation namespace, you must set `stackitSaAuthentication.secretAccessScope=issuer` when installing the Helm chart.
### Option B: Static Service Account Key (Single Tenant / Global Fallback)
65
+
66
+
This method mounts a single Service Account key JSON file into the webhook Pod. It is ideal for single-tenant clusters where the webhook manages domains for a single STACKIT project or organization.
67
+
68
+
1. **Deploy the Webhook with the Key Mounted:**
69
+
Create a secret in the `cert-manager` namespace and install the Helm chart with mounting enabled:
email: example@example.com # Replace this with your email address
88
-
privateKeySecretRef:
89
-
name: letsencrypt-prod
90
-
solvers:
91
-
- dns01:
92
-
webhook:
93
-
solverName: stackit
94
-
groupName: acme.stackit.de
95
-
config:
96
-
projectId: <STACKIT PROJECT ID>
97
-
```
98
-
*Note on service accounts and namespaces:*
99
-
- Issuer-per-namespace (recommended forisolation): create a STACKIT service-account key (sa.json) for each STACKIT project you need to manage and place that keyin a Kubernetes Secret in the same namespace as the Issuer. This means one sa.json (one SA key) per Issuer/namespace when the Issuers target different STACKIT projects.
100
-
Example (create a secret in the Issuer namespace):
Ensure the webhook can read the secret in that namespace (create the secret where the Issuer lives).
107
-
- Alternative (single SA key for multiple projects): you can grant the service account broader permissions at folder or organization level so one sa.json can manage zones across multiple projects. This is more convenient but grants wider access — evaluate security and follow least-privilege principles.
108
-
- Tradeoffs:
109
-
- Per-namespace/per-project SA keys: better isolation and least privilege, easier to rotate keys per project.
110
-
- Folder/org-level SA key: lower operational overhead (single key), but larger blast radius if compromised.
111
-
112
-
3. ***Demonstration of Ingress Integration with Wildcard SSL/TLS Certificate Generation***
113
-
Given the preceding configuration, it is possible to exploit the capabilities of the Issuer or ClusterIssuer to
114
-
dynamically produce wildcard SSL/TLS certificates in the following manner:
115
-
```yaml
116
-
apiVersion: cert-manager.io/v1
117
-
kind: Certificate
118
-
metadata:
119
-
name: wildcard-example
120
-
namespace: default
121
-
spec:
122
-
secretName: wildcard-example-tls
123
-
issuerRef:
124
-
name: letsencrypt-prod
125
-
kind: Issuer
126
-
commonName: '*.example.runs.onstackit.cloud'# project must be the owner of this zone
If your cluster supports Workload Identity Federation (e.g., SKE clusters), you can avoid managing long-lived keys entirely by projecting a short-lived token into the webhook container.
106
+
107
+
1. **Annotate the Webhook ServiceAccount:**
108
+
Update your Helm deployment to instruct the identity webhook to inject the federated token.
| `serviceAccountBaseUrl` | string | `""` | Custom URL for trading SA keys for access tokens. |
150
+
| `acmeTxtRecordTTL` | int32 | `60` | The TTL for the ACME TXT challenge record. |
192
151
193
152
## Test Procedures
194
153
@@ -210,12 +169,13 @@ make lint
210
169
### Go Conformance Testing:
211
170
Runs the official cert-manager Go solver test suite in memory against the STACKIT API:
212
171
```bash
213
-
STACKIT_TOKEN="<token>"TEST_ZONE_NAME="example.com" make test-e2e-conformance
172
+
TEST_ZONE_NAME="example.com" make test-e2e-conformance
214
173
```
215
174
Follow the comprehensive guide available [here](e2e_test/README.md).
216
175
217
176
### Kubernetes Integration (E2E) Testing:
218
-
Spins up a local Kind cluster, installs cert-manager, builds and deploys the webhook, and executes Kuttl integration tests (testing single-record lifecycle and wildcard certificates against Let's Encrypt Staging):
177
+
Spins up a local Kind cluster, installs cert-manager, builds and deploys the webhook, and executes Kuttl integration tests covering both single-tenant (static fallback) and multi-tenant (dynamic SA fetching) flows against Let's Encrypt Staging:
0 commit comments