Skip to content

Commit 8c90478

Browse files
committed
[k8s] add 'certs list/rotate/revoke' subcommands
Customer-facing cert lifecycle for the in-cluster kube-controller's service-account cert (Secret apoxy/apiz-cert). - list: parses tls.crt from the Secret, prints fingerprint + expiry, looks up server-side status via GET /v1/terra/serviceaccount/ certificate/<fp>. --all also lists every cert cosmos has for the project (active + revoked). - rotate: issues a new cert, atomically swaps Secret data with a ResourceVersion-gated Update, patches the Deployment pod template (cert-rotated-at + cert-fingerprint annotations) to trigger a RollingUpdate. Single-replica controller + maxSurge=1, maxUnavailable=0 keeps the aggregated APIService routable through the swap because the old pod's in-memory cert stays valid in cosmos until explicit revoke. --revoke combines the two; --wait-timeout=0 skips the rollout poll for dev where /healthz aggregates tunnel readiness. - revoke: DELETE /v1/terra/serviceaccount/certificate/<fp> with a user JWT (PropelAuth access token). cosmos refuses API-key auth here so a leaked API key can't kill the cert it lives next to. JWT precedence: --user-jwt > APOXY_USER_JWT > ~/.config/apoxy/user-jwt. Includes pkg/cert/fingerprint.go (SHA1 hex of DER, NormalizeFingerprint) mirroring apoxy-cloud/core/cert without taking a cosmos module dep. Unit tests cover the fingerprint helper, the safe-strategy guard (refuses Recreate or multi-replica without --allow-disruption), and the JWT precedence chain. Design + customer guide in apoxy-cloud: - docs/kube-controller-auth.md - run/docs/content/docs/guides/rotating-kube-controller-cert.mdx Integration coverage: //tests/integration/kube-controller (drives the full install -> list -> rotate flow against dev Tilt cluster in <10s).
1 parent b721dfb commit 8c90478

3 files changed

Lines changed: 847 additions & 0 deletions

File tree

pkg/cert/fingerprint.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Package cert provides X.509 fingerprint helpers used by the CLI's cert
2+
// subcommands. Mirrors github.com/apoxy-dev/apoxy-cloud/core/cert so the
3+
// CLI doesn't pull a cosmos module dependency.
4+
package cert
5+
6+
import (
7+
"crypto/sha1"
8+
"encoding/hex"
9+
"fmt"
10+
"strings"
11+
)
12+
13+
// FingerprintSize is the byte length of a SHA1 cert fingerprint.
14+
const FingerprintSize = sha1.Size
15+
16+
// Fingerprint returns the lowercase hex SHA1 of the cert's DER bytes. The
17+
// resulting string is the canonical form cosmos persists and what
18+
// ext_authz / RevokeServiceCert compare against.
19+
func Fingerprint(certDER []byte) string {
20+
return fmt.Sprintf("%x", sha1.Sum(certDER))
21+
}
22+
23+
// NormalizeFingerprint validates and lowercases a SHA1 fingerprint string.
24+
func NormalizeFingerprint(s string) (string, error) {
25+
s = strings.ToLower(s)
26+
b, err := hex.DecodeString(s)
27+
if err != nil || len(b) != FingerprintSize {
28+
return "", fmt.Errorf("fingerprint must be a 40-character SHA1 hex string")
29+
}
30+
return s, nil
31+
}

0 commit comments

Comments
 (0)