Skip to content

Commit 9d5ca23

Browse files
committed
docs: revamp README
1 parent 4d8b92b commit 9d5ca23

1 file changed

Lines changed: 66 additions & 92 deletions

File tree

README.md

Lines changed: 66 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,43 @@ Kubernetes operator to manage fine-grained, ephemeral Access Tokens generated fr
99

1010
## Description
1111

12-
A number of Kubernetes operators, including [FluxCD](https://fluxcd.io/) and [upbound/provider-terraform](https://github.com/upbound/provider-terraform), often need to authenticate with the GitHub API, particularly when private repositories are used. This may be to clone a private repository, pull from a private GHCR repository, or to send a commit or deployment status. Common practice is to use Personal Access Tokens (PATs), but their use is far from optimal: PATs tending to be long-lived, poorly scoped, and tied to an individual, as GitHub has no official support for service accounts.
12+
Kubernetes operators like [FluxCD](https://fluxcd.io/) and [crossplane-contrib/provider-terraform](https://github.com/crossplane-contrib/provider-terraform) need GitHub API access for private repositories, container registry pulls, and status updates. The traditional approaches have critical flaws: Personal Access Tokens (PATs) are long-lived, over-privileged, and tied to individuals, while storing GitHub App private keys in-cluster creates massive security risks.
1313

14-
This operator functions similarly to cert-manager, but instead of managing certificates, it manages GitHub App Installation Access Tokens. It takes custom-scoped `Token` (namespaced) and `ClusterToken` requests and transforms them into `Secrets`. These `Secrets` contain regularly refreshed GitHub App Installation Access Token credentials. These credentials are ready for use with GitHub clients that rely on HTTP Basic Auth, providing a more secure and automated solution for token management.
14+
This operator solves the problem by functioning like cert-manager for GitHub tokens. It automatically generates ephemeral, fine-grained access tokens from GitHub App credentials stored securely in cloud Key Management Services, never exposing private keys in your cluster.
15+
16+
## Features
17+
18+
- **🔐 Zero-Trust Security**: Never store GitHub App private keys in-cluster - integrates with AWS KMS, Google Cloud KMS, and HashiCorp Vault
19+
- **⏰ Ephemeral & Auto-Rotating**: Tokens expire in 1 hour and refresh automatically before expiration
20+
- **🎯 Fine-Grained Permissions**: Each token can have different scopes, down to specific repositories and permissions
21+
- **🏢 Multi-Tenancy**: Namespace isolation with `Token` CRD, cluster-wide control with `ClusterToken`
22+
- **🚀 GitOps-Ready**: Native FluxCD integration with HTTP Basic Auth secret generation
23+
- **📊 Production-Ready**: Prometheus metrics, health probes, intelligent retry logic with exponential backoff
1524

1625
## Getting Started
1726

1827
### Prerequisites
1928

20-
* A Kubernetes cluster (v1.21+)
21-
* A [GitHub App](https://docs.github.com/en/apps/creating-github-apps) with permissions and repository assignments sufficient to meet the needs of all anticipated GitHub API interactions. Typically: `metadata: read`, `contents: read`, `statuses: write`.
22-
* Specifically: App ID, App Installation ID and a Private Key are required.
29+
- Kubernetes cluster (v1.30+)
30+
- [GitHub App](https://docs.github.com/en/apps/creating-github-apps) with required permissions (typically: `metadata: read`, `contents: read`, `statuses: write`)
31+
- GitHub App ID and Installation ID, with private key stored in AWS KMS, Google Cloud KMS, or HashiCorp Vault
2332

2433
### Installation
2534

26-
A Helm Chart is provided your for convenience: [deploy/charts/github-token-manager/](deploy/charts/github-token-manager/)
35+
```bash
36+
# Helm (recommended)
37+
helm install oci://ghcr.io/isometry/charts/github-token-manager ./deploy/charts/github-token-manager
2738

28-
Alternatively, a baseline Kustomization is provided under [config/default/](config/default/)
39+
# Or Kustomize
40+
kustomize build config/default | kubectl apply -f -
41+
```
2942

3043
### Configuration
3144

32-
The operator itself requires configuration via `ConfigMap/gtm-config` in its deployment namespace. This contains the GitHub App ID, Installation ID and Private Key provider details. In addition to embedding the private key file within the secret, AWS Key Management Service (KMS), Google Cloud Key Management, and HashiCorp Vault's Transit Secrets Engine are also supported for secure external handling of keying material.
33-
34-
#### Example `gtm-config` with embedded Private Key
45+
Configure via `Secret/gtm-config` with your GitHub App details and secure key storage:
3546

3647
```yaml
48+
# AWS KMS (recommended)
3749
apiVersion: v1
3850
kind: Secret
3951
metadata:
@@ -43,17 +55,12 @@ stringData:
4355
gtm.yaml: |
4456
app_id: 1234
4557
installation_id: 4567890
46-
provider: file
47-
key: /config/private.key
48-
private.key: |
49-
-----BEGIN RSA PRIVATE KEY-----
50-
...elided...
51-
-----END RSA PRIVATE KEY-----
58+
provider: aws
59+
key: alias/github-token-manager
5260
```
5361
54-
#### Example `gtm-config` with AWS KMS
55-
5662
```yaml
63+
# File-based (for development/testing)
5764
apiVersion: v1
5865
kind: Secret
5966
metadata:
@@ -62,18 +69,36 @@ metadata:
6269
stringData:
6370
gtm.yaml: |
6471
app_id: 1234
65-
installation_id: 45678890
66-
provider: aws
67-
key: alias/github-token-manager
72+
installation_id: 4567890
73+
provider: file
74+
key: /config/private.key
75+
private.key: |
76+
-----BEGIN RSA PRIVATE KEY-----
77+
...your GitHub App private key...
78+
-----END RSA PRIVATE KEY-----
6879
```
6980
70-
### `Token` and `ClusterToken`
81+
**Cloud KMS Permissions Required:**
82+
83+
- **AWS KMS**: IAM permissions `kms:DescribeKey` and `kms:Sign` on the KMS key
84+
- **GCP KMS**: Permission `cloudkms.cryptoKeyVersions.useToSign` or role `roles/cloudkms.cryptoKeyVersionsSigner`
85+
- **Vault**: Policy with `write` capability on transit sign path (e.g., `transit/sign/<keyName>`)
7186

72-
Once the operator is installed and configured, any number of namespaced `Token` and non-namespaced `ClusterToken` may be created, resulting in matching `Secret` resoures being created, containing either `token` or `username` and `password` fields, depending on configuration.
87+
**Pod Authentication:**
7388

74-
The namespaced `Token` resource manages a `Secret` in the same namespace containing a fine-grained [installation access token](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app) for the configured GitHub App, appropriate for delegated management by the namespace owner.
89+
- **AWS**: IRSA, Pod Identity, or instance profile with above KMS permissions
90+
- **GCP**: Workload Identity or service account with Cloud KMS access
91+
- **Vault**: Kubernetes auth method configured with appropriate transit policy
7592

76-
The non-namespaced `ClusterToken` resource does the same thing, but supports abstracted management where only the managed `Secret` is bound to the configured target namespace via `.spec.secret.namespace`.
93+
Supported providers: `aws` (KMS), `gcp` (Cloud KMS), `vault` (Transit Engine), `file` (embedded)
94+
95+
### Token Resources
96+
97+
Create `Token` (namespaced) or `ClusterToken` (cluster-scoped) resources to generate secure `Secret` objects:
98+
99+
- **Token**: Namespace-isolated, delegated management
100+
- **ClusterToken**: Centralized control with target namespace specification
101+
- **Secrets**: Contain `token` field or `username`/`password` for HTTP Basic Auth
77102

78103
```yaml
79104
apiVersion: github.as-code.io/v1
@@ -95,9 +120,9 @@ spec:
95120
namespace: default # (required, ClusterToken-only) set the target namespace for managed `Secret`
96121
```
97122
98-
#### Examples
123+
### Examples
99124
100-
Manage a `Secret/github-token` containing HTTP Basic Auth `username` and `password` fields appropriate for use with a Flux' `GitRepository` [Secret Reference](https://fluxcd.io/flux/components/source/gitrepositories/#secret-reference):
125+
**FluxCD Git Repository Access:**
101126
102127
```yaml
103128
apiVersion: github.as-code.io/v1
@@ -109,12 +134,11 @@ spec:
109134
permissions:
110135
metadata: read
111136
contents: read
112-
refreshInterval: 45m
113137
secret:
114-
basicAuth: true
138+
basicAuth: true # Creates username/password for Git
115139
```
116140
117-
Manage a `Secret/github-status` containing a plain `token` field appropriate for use with a Flux' `Provider` [GitHub Commit Status Updates](https://fluxcd.io/flux/components/notification/providers/#github):
141+
**GitHub API Status Updates:**
118142
119143
```yaml
120144
apiVersion: github.as-code.io/v1
@@ -126,77 +150,27 @@ spec:
126150
permissions:
127151
metadata: read
128152
statuses: write
129-
refreshInterval: 45m
130153
```
131154
132-
Manage `Secret/github` in the `default` namespace containing a plain `token` field, inheriting all permissions assigned to the configured GitHub App:
155+
## Development
133156
134-
```yaml
135-
apiVersion: github.as-code.io/v1
136-
kind: ClusterToken
137-
metadata:
138-
name: default-github
139-
spec:
140-
secret:
141-
name: github
142-
namespace: default
143-
```
144-
145-
## Contributing
146-
147-
All contributions from the community are welcome.
148-
149-
**NOTE:** Run `make help` for more information on all potential `make` targets
150-
151-
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
152-
153-
### To Deploy on the cluster
154-
155-
156-
#### Build and push your image to the location specified by `IMG`:
157-
158-
```sh
159-
make ko-build IMG=<some-registry>/github-token-manager:tag
160-
```
157+
```bash
158+
# Build and test
159+
make build test lint
161160

162-
**NOTE:** This image ought to be published in the personal registry you specified.
163-
And it is required to have access to pull the image from the working environment.
164-
Make sure you have the proper permission to the registry if the above commands don’t work.
161+
# Deploy locally
162+
make ko-build IMG=<registry>/github-token-manager:tag
163+
make deploy IMG=<registry>/github-token-manager:tag
165164

166-
#### Install the CRDs into the cluster:
167-
168-
```sh
169-
make install
170-
```
171-
172-
#### Deploy the Manager to the cluster with the image specified by `IMG`:
173-
174-
```sh
175-
make deploy IMG=<some-registry>/github-token-manager:tag
165+
# Clean up
166+
make undeploy uninstall
176167
```
177168

178-
> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin
179-
privileges or be logged in as admin.
169+
Run `make help` for all available targets. See [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) for details.
180170

181-
### To Uninstall
182-
183-
#### Delete the instances (CRs) from the cluster
184-
185-
```sh
186-
kubectl delete -k config/samples/
187-
```
188-
189-
#### Delete the APIs(CRDs) from the cluster
190-
191-
```sh
192-
make uninstall
193-
```
194-
195-
#### UnDeploy the controller from the cluster
171+
## Contributing
196172

197-
```sh
198-
make undeploy
199-
```
173+
Contributions are welcome! Please submit pull requests via GitHub. For major changes, please open an issue first to discuss your proposed changes.
200174

201175
## License
202176

0 commit comments

Comments
 (0)