Skip to content

Commit 929ff4b

Browse files
committed
feat(groups): add ServiceAccountAccessToken managed resource
Adds a group-scoped ServiceAccountAccessToken managed resource that manages the personal access token of a group service account. Owner mode (default): the ProviderConfig is a group owner and the token is managed via the service-account endpoints: - Create -> Groups.CreateServiceAccountPersonalAccessToken - Observe -> Groups.ListServiceAccountPersonalAccessTokens (match by token id) - Rotate -> Groups.RotateServiceAccountPersonalAccessToken - Revoke -> Groups.RevokeServiceAccountPersonalAccessToken Self-managed mode: when the referenced ProviderConfig authenticates with the very token this resource writes to its connection secret (detected when the PersonalAccessToken credential secretRef matches writeConnectionSecretToRef by namespace, name and key), the provider acts as the service account itself and uses the self endpoints instead: - Observe -> GET /personal_access_tokens/self (self-inform; external name is auto-adopted from the response) - Rotate -> RotatePersonalAccessTokenSelf - Revoke -> RevokePersonalAccessTokenSelf This enables a self-sustaining loop of short-lived, self-rotating tokens used to reconcile a group. A dead self-token surfaces as a clear terminal error (reseed the credentials secret). A SelfManaged status condition reports the detected mode. The external name is the token id and the token value is written to the connection secret on create/rotate. Rotation, expiresAt/renewalPeriodDays and renewBeforeDays semantics match the group AccessToken controller. groupId, serviceAccountId, name and scopes are immutable (enforced via CEL); the rotation-timing fields stay mutable. Fixes #324 Signed-off-by: Markus Siebert <markus.siebert@deutschebahn.com>
1 parent 845e4d7 commit 929ff4b

29 files changed

Lines changed: 5338 additions & 4 deletions

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,51 @@ spec:
4444
kubectl apply -f examples/providerconfig/provider.yaml
4545
```
4646

47+
### Self-rotating service account tokens
48+
49+
The namespaced `groups.gitlab.m.crossplane.io/v1alpha1` `ServiceAccountAccessToken`
50+
resource can keep a short-lived token alive by rotating it before it expires.
51+
52+
It supports two modes, selected automatically:
53+
54+
* **Owner mode** (default): the `ProviderConfig` is a group owner. The token is
55+
created, observed, rotated and revoked through the group service-account
56+
endpoints.
57+
* **Self-managed mode**: the `ProviderConfig` authenticates with the *very token*
58+
this resource manages — i.e. the `ProviderConfig.credentials.secretRef` points
59+
at the same secret (namespace, name and `token` key) that the resource writes
60+
via `writeConnectionSecretToRef`. The provider then acts as the service account
61+
itself and uses the self endpoints (`GET/POST /personal_access_tokens/self`).
62+
This lets a short-lived token reconcile a whole group and keep itself alive by
63+
self-rotating. A `SelfManaged` status condition reports the active mode.
64+
65+
> **Bootstrap secret type.** In self-managed mode the rotated token is written
66+
> back into the secret the `ProviderConfig` reads. Crossplane only writes
67+
> connection secrets it controls, so a **hand-created** bootstrap secret must use
68+
> the connection secret type `connection.crossplane.io/v1alpha1` — a default
69+
> `Opaque` secret (e.g. from `kubectl create secret generic`, which has no
70+
> `--type` flag) is rejected with `refusing to modify uncontrolled secret of type
71+
> "Opaque"`. Create it from a manifest:
72+
>
73+
> ```yaml
74+
> apiVersion: v1
75+
> kind: Secret
76+
> metadata:
77+
> name: gitlab-self-rotating-token
78+
> namespace: default
79+
> type: connection.crossplane.io/v1alpha1
80+
> stringData:
81+
> # a service account PAT with at least the `api` and `self_rotate` scopes
82+
> token: "<PERSONAL_ACCESS_TOKEN>"
83+
> ```
84+
>
85+
> Alternatively, bootstrap in owner mode first (Crossplane then creates and owns
86+
> a correctly typed connection secret), and switch `providerConfigRef` to the
87+
> self `ProviderConfig` afterwards.
88+
89+
See [`examples/groups/serviceaccountaccesstoken.yaml`](examples/groups/serviceaccountaccesstoken.yaml)
90+
for full examples of both modes.
91+
4792
## Contributing
4893
4994
provider-gitlab is a community driven project and we welcome contributions. See

apis/cluster/groups/v1alpha1/zz_generated.deepcopy.go

Lines changed: 198 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/cluster/groups/v1alpha1/zz_generated.managed.go

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/cluster/groups/v1alpha1/zz_generated.managedlist.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/cluster/groups/v1alpha1/zz_referencers.go

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)