Implement KeyCape service-token issuance
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 47s

This commit is contained in:
tegwick 2026-07-27 20:03:07 +02:00
parent 519f0772d2
commit e877d2752d
10 changed files with 348 additions and 43 deletions

View file

@ -73,7 +73,11 @@ func main() {
// -----------------------------------------------------------------
// 5. Build client registry.
// -----------------------------------------------------------------
clients := buildClientRegistry(cfg.Clients)
clients, err := buildClientRegistry(cfg.Clients)
if err != nil {
log.Error().Err(err).Msg("failed to build client registry")
os.Exit(1)
}
// -----------------------------------------------------------------
// 6. Create adapters.
@ -148,7 +152,7 @@ func main() {
ClientConfig: clients,
Sessions: sessions,
Users: lldapAdapter,
SigningKey: privateKey,
SigningKey: privateKey,
Issuer: issuer,
TokenLifetime: tokenLifetime,
Emitter: emitter,
@ -157,10 +161,10 @@ func main() {
// Userinfo handler.
mux.Handle("/userinfo", &oidc.UserinfoHandler{
Users: lldapAdapter,
Users: lldapAdapter,
SigningKey: &privateKey.PublicKey,
Issuer: issuer,
Emitter: emitter,
Issuer: issuer,
Emitter: emitter,
})
// Healthz.
@ -245,21 +249,33 @@ func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
}
// buildClientRegistry converts []ClientConfig into the map used by handlers.
func buildClientRegistry(cfgClients []config.ClientConfig) map[string]*domain.Client {
func buildClientRegistry(cfgClients []config.ClientConfig) (map[string]*domain.Client, error) {
m := make(map[string]*domain.Client, len(cfgClients))
for i := range cfgClients {
c := &cfgClients[i]
clientSecret := ""
if strings.HasPrefix(c.SecretRef, "env:") {
envName := strings.TrimPrefix(c.SecretRef, "env:")
clientSecret = os.Getenv(envName)
if clientSecret == "" {
return nil, fmt.Errorf("client %q secret environment variable %q is empty", c.ClientID, envName)
}
}
m[c.ClientID] = &domain.Client{
ClientID: c.ClientID,
DisplayName: c.DisplayName,
RedirectURIs: c.RedirectURIs,
AllowedScopes: c.AllowedScopes,
GrantTypes: c.GrantTypes,
ClientType: c.ClientType,
SecretRef: c.SecretRef,
ClientID: c.ClientID,
DisplayName: c.DisplayName,
RedirectURIs: c.RedirectURIs,
AllowedScopes: c.AllowedScopes,
GrantTypes: c.GrantTypes,
ClientType: c.ClientType,
SecretRef: c.SecretRef,
ClientSecret: clientSecret,
ServiceSubject: c.ServiceSubject,
Tenant: c.Tenant,
Roles: c.Roles,
}
}
return m
return m, nil
}
// withEmitter wraps a handler to inject the telemetry emitter into every request context.