Skip to content

Commit a9c268a

Browse files
committed
feat: Add Azure Key Vault support and validate_key option
- Add Azure Key Vault as a supported provider for GitHub App private keys - Add validate_key option to check key accessibility and suitability at startup - Update Helm chart and documentation for Azure and validate_key, bumping version to 0.3.0 - Bump go-github and ghait dependencies to v84
1 parent 62da49a commit a9c268a

20 files changed

Lines changed: 121 additions & 29 deletions

File tree

README.md

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ This operator solves the problem by functioning like cert-manager for GitHub tok
1515

1616
## Features
1717

18-
- **🔐 Zero-Trust Security**: Never store GitHub App private keys in-cluster - integrates with AWS KMS, Google Cloud KMS, and HashiCorp Vault
18+
- **🔐 Zero-Trust Security**: Never store GitHub App private keys in-cluster - integrates with AWS KMS, Azure Key Vault, Google Cloud KMS, and HashiCorp Vault
1919
- **⏰ Ephemeral & Auto-Rotating**: Tokens expire in 1 hour and refresh automatically before expiration
2020
- **🎯 Fine-Grained Permissions**: Each token can have different scopes, down to specific repositories and permissions
2121
- **🏢 Multi-Tenancy**: Namespace isolation with `Token` CRD, cluster-wide control with `ClusterToken`
@@ -28,7 +28,7 @@ This operator solves the problem by functioning like cert-manager for GitHub tok
2828

2929
- Kubernetes cluster (v1.30+)
3030
- [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
31+
- GitHub App ID and Installation ID, with private key stored in AWS KMS, Azure Key Vault, Google Cloud KMS, or HashiCorp Vault
3232

3333
### Installation
3434

@@ -57,6 +57,22 @@ stringData:
5757
installation_id: 4567890
5858
provider: aws
5959
key: alias/github-token-manager
60+
validate_key: true # optional: validate key on startup
61+
```
62+
63+
```yaml
64+
# Azure Key Vault
65+
apiVersion: v1
66+
kind: Secret
67+
metadata:
68+
name: gtm-config
69+
namespace: github-token-manager
70+
stringData:
71+
gtm.yaml: |
72+
app_id: 1234
73+
installation_id: 4567890
74+
provider: azure
75+
key: https://<vault-name>.vault.azure.net/keys/<key-name>
6076
```
6177
6278
```yaml
@@ -78,19 +94,33 @@ stringData:
7894
-----END RSA PRIVATE KEY-----
7995
```
8096
97+
**Configuration Fields:**
98+
99+
| Field | Required | Default | Description |
100+
|-------|----------|---------|-------------|
101+
| `app_id` | yes | | GitHub App ID |
102+
| `installation_id` | yes | | GitHub App Installation ID |
103+
| `provider` | no | `file` | Key provider: `aws`, `azure`, `gcp`, `vault`, or `file` |
104+
| `key` | yes | | Key identifier (alias, URI, path, or embedded key depending on provider) |
105+
| `validate_key` | no | `false` | Validate the key on startup, failing fast on misconfiguration |
106+
107+
When `validate_key` is enabled, the operator verifies at startup that the configured key is accessible and suitable for signing. This requires additional read permissions on the key (e.g., `kms:DescribeKey` for AWS, `keys/get` for Azure, `cloudkms.cryptoKeyVersions.get` for GCP, `read` on the key path for Vault).
108+
81109
**Cloud KMS Permissions Required:**
82110

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>`)
111+
- **AWS KMS**: `kms:Sign` on the KMS key (+ `kms:DescribeKey` if `validate_key` is enabled)
112+
- **Azure Key Vault**: `keys/sign` on the key (+ `keys/get` if `validate_key` is enabled)
113+
- **GCP KMS**: `cloudkms.cryptoKeyVersions.useToSign` or role `roles/cloudkms.cryptoKeyVersionsSigner` (+ `cloudkms.cryptoKeyVersions.get` if `validate_key` is enabled)
114+
- **Vault**: `write` capability on transit sign path, e.g. `transit/sign/<keyName>` (+ `read` on `transit/keys/<keyName>` if `validate_key` is enabled)
86115

87116
**Pod Authentication:**
88117

89118
- **AWS**: IRSA, Pod Identity, or instance profile with above KMS permissions
119+
- **Azure**: Workload Identity or managed identity with Key Vault access
90120
- **GCP**: Workload Identity or service account with Cloud KMS access
91121
- **Vault**: Kubernetes auth method configured with appropriate transit policy
92122

93-
Supported providers: `aws` (KMS), `gcp` (Cloud KMS), `vault` (Transit Engine), `file` (embedded)
123+
Supported providers: `aws` (KMS), `azure` (Key Vault), `gcp` (Cloud KMS), `vault` (Transit Engine), `file` (embedded)
94124

95125
### Token Resources
96126

@@ -152,6 +182,20 @@ spec:
152182
statuses: write
153183
```
154184
185+
## Custom Builds
186+
187+
The default build includes all KMS providers (AWS, Azure, GCP, Vault, file). To produce a smaller binary that excludes unwanted providers and their dependencies, use Go build tags:
188+
189+
```bash
190+
# Exclude AWS and Azure providers
191+
go build -tags ghait.no_aws,ghait.no_azure ./cmd/manager
192+
193+
# Build with only file and Vault providers
194+
go build -tags ghait.no_aws,ghait.no_azure,ghait.no_gcp ./cmd/manager
195+
```
196+
197+
Available opt-out tags: `ghait.no_aws`, `ghait.no_azure`, `ghait.no_gcp`, `ghait.no_vault`, `ghait.no_file`
198+
155199
## Development
156200

157201
```bash

api/v1/clustertoken_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package v1
1919
import (
2020
"time"
2121

22-
"github.com/google/go-github/v80/github"
22+
"github.com/google/go-github/v84/github"
2323
"github.com/isometry/github-token-manager/internal/ghapp"
2424
"k8s.io/apimachinery/pkg/api/meta"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

api/v1/clustertoken_types_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"testing"
55
"time"
66

7-
"github.com/google/go-github/v80/github"
7+
"github.com/google/go-github/v84/github"
88
v1 "github.com/isometry/github-token-manager/api/v1"
99
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010
)

api/v1/helpers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package v1_test
33
import (
44
"testing"
55

6-
"github.com/google/go-github/v80/github"
6+
"github.com/google/go-github/v84/github"
77
v1 "github.com/isometry/github-token-manager/api/v1"
88
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
99
)

api/v1/permissions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package v1
22

33
import (
4-
"github.com/google/go-github/v80/github"
4+
"github.com/google/go-github/v84/github"
55
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
66
)
77

api/v1/token_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package v1
1919
import (
2020
"time"
2121

22-
"github.com/google/go-github/v80/github"
22+
"github.com/google/go-github/v84/github"
2323
"github.com/isometry/github-token-manager/internal/ghapp"
2424
"k8s.io/apimachinery/pkg/api/meta"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

api/v1/token_types_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"testing"
55
"time"
66

7-
"github.com/google/go-github/v80/github"
7+
"github.com/google/go-github/v84/github"
88
v1 "github.com/isometry/github-token-manager/api/v1"
99
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010
)

deploy/charts/github-token-manager/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ name: github-token-manager
44
description: A Helm chart for github-token-manager
55

66
type: application
7-
version: 0.2.0
7+
version: 0.3.0

deploy/charts/github-token-manager/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,20 @@ config.app_id | GitHub App ID | `0` |
2828
config.installation_id | GitHub App Installation ID | `0` |
2929
config.provider | GitHub App Private Key Provider | `aws` |
3030
config.key | GitHub App Private Key Path | `alias/github-token-manager` |
31+
config.validate_key | Validate the key on startup | `false` |
3132
rbac.serviceAccount.annotations | Annotations for the service account | `{}` |
3233
commonAnnotations | Common annotations for all resources | `{}` |
3334

3435
The `config.provider` field supported options are:
3536
- `aws`: The GitHub App private key is stored in AWS KMS (asymmetric, RSA_2048, sign and verify key) and the `config.key` field should be set to the alias of this KMS key.
37+
- `azure`: The GitHub App private key is stored in Azure Key Vault and the `config.key` field should be set to the key URI (e.g. `https://<vault-name>.vault.azure.net/keys/<key-name>`).
3638
- `file`: The GitHub App private key is embedded by YAML multiline string in the `config.key` field.
3739
- `gcp`: The GitHub App private key is stored in GCP KMS.
38-
- `vault`: The GitHub App private key is stored in HashiCorp Vault.
40+
- `vault`: The GitHub App private key is stored in HashiCorp Vault Transit Engine.
3941

40-
When using external providers like `aws`, `gcp`, or `vault`, the controller's `ServiceAccount` must be configured with the necessary permissions to access the external store.
42+
When `config.validate_key` is set to `true`, the operator validates that the configured key is accessible and suitable for signing at startup, failing fast on misconfiguration. This may require additional read permissions on the key.
43+
44+
When using external providers like `aws`, `azure`, `gcp`, or `vault`, the controller's `ServiceAccount` must be configured with the necessary permissions to access the external store.
4145

4246
### Example values.yaml configuration for aws provider
4347

deploy/charts/github-token-manager/templates/config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ stringData:
1818
app_id: {{ .Values.config.app_id | int }}
1919
installation_id: {{ .Values.config.installation_id | int }}
2020
provider: "{{ .Values.config.provider }}"
21+
{{- if .Values.config.validate_key }}
22+
validate_key: true
23+
{{- end }}
2124
{{- if ne .Values.config.provider "file" }}
2225
key: "{{ .Values.config.key }}"
2326
{{- else }}

0 commit comments

Comments
 (0)