diff --git a/cmd/kes/identity.go b/cmd/kes/identity.go index e2772776..b449d7d9 100644 --- a/cmd/kes/identity.go +++ b/cmd/kes/identity.go @@ -500,7 +500,7 @@ func infoIdentityCmd(args []string) { cli.Fatal(err) } year, month, day := info.CreatedAt.Date() - hour, min, sec := info.CreatedAt.Clock() + hour, minute, sec := info.CreatedAt.Clock() fmt.Println( faint.Render(fmt.Sprintf("%-11s", "Identity")), @@ -508,7 +508,7 @@ func infoIdentityCmd(args []string) { ) fmt.Println( faint.Render(fmt.Sprintf("%-11s", "Created At")), - fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec), + fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, sec), ) if info.IsAdmin { fmt.Println(faint.Render(fmt.Sprintf("%-11s", "Role")), "Admin") @@ -520,13 +520,13 @@ func infoIdentityCmd(args []string) { } if info.Policy != "" { year, month, day := policy.CreatedAt.Date() - hour, min, sec := policy.CreatedAt.Clock() + hour, minute, sec := policy.CreatedAt.Clock() fmt.Println() fmt.Println(faint.Render(fmt.Sprintf("%-11s", "Policy")), policyStyle.Render(info.Policy)) fmt.Println( faint.Render(fmt.Sprintf("%-11s", "Created At")), - fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec), + fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, sec), ) if len(policy.Allow) > 0 { fmt.Println(faint.Render(fmt.Sprintf("%-11s", "Allow"))) @@ -547,7 +547,7 @@ func infoIdentityCmd(args []string) { cli.Fatal(err) } year, month, day := info.CreatedAt.Date() - hour, min, sec := info.CreatedAt.Clock() + hour, minute, sec := info.CreatedAt.Clock() fmt.Println( faint.Render(fmt.Sprintf("%-11s", "Identity")), @@ -558,7 +558,7 @@ func infoIdentityCmd(args []string) { } fmt.Println( faint.Render(fmt.Sprintf("%-11s", "Created At")), - fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec), + fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, sec), ) if info.IsAdmin { fmt.Println(faint.Render(fmt.Sprintf("%-11s", "Role")), "Admin") diff --git a/cmd/kes/key.go b/cmd/kes/key.go index b79915f2..d0a21367 100644 --- a/cmd/kes/key.go +++ b/cmd/kes/key.go @@ -251,12 +251,12 @@ func describeKeyCmd(args []string) { } year, month, day := info.CreatedAt.Date() - hour, min, sec := info.CreatedAt.Clock() + hour, minute, sec := info.CreatedAt.Clock() buf := &strings.Builder{} fmt.Fprintf(buf, "%-11s %s\n", "Name", info.Name) fmt.Fprintf(buf, "%-11s %s\n", "Algorithm", info.Algorithm) - fmt.Fprintf(buf, "%-11s %04d-%02d-%02d %02d:%02d:%02d\n", "Date", year, month, day, hour, min, sec) + fmt.Fprintf(buf, "%-11s %04d-%02d-%02d %02d:%02d:%02d\n", "Date", year, month, day, hour, minute, sec) fmt.Fprintf(buf, "%-11s %s", "Owner", info.CreatedBy) fmt.Print(buf) } diff --git a/cmd/kes/log.go b/cmd/kes/log.go index b170e7a9..ccb91bb1 100644 --- a/cmd/kes/log.go +++ b/cmd/kes/log.go @@ -135,11 +135,11 @@ func printAuditLog(stream *kes.AuditStream) { for stream.Next() { event := stream.Event() var ( - hour, min, sec = event.Timestamp.Clock() - status = strconv.Itoa(event.StatusCode) - identity = identityStyle.Render(event.ClientIdentity.String()) - apiPath = apiStyle.Render(event.APIPath) - latency = event.ResponseTime + hour, minute, sec = event.Timestamp.Clock() + status = strconv.Itoa(event.StatusCode) + identity = identityStyle.Render(event.ClientIdentity.String()) + apiPath = apiStyle.Render(event.APIPath) + latency = event.ResponseTime ) if event.StatusCode == http.StatusOK { @@ -167,7 +167,7 @@ func printAuditLog(stream *kes.AuditStream) { } ipAddr = ipStyle.Render(ipAddr) - fmt.Printf(format, hour, min, sec, status, identity, ipAddr, apiPath, latency) + fmt.Printf(format, hour, minute, sec, status, identity, ipAddr, apiPath, latency) } if err := stream.Close(); err != nil { if errors.Is(err, context.Canceled) { diff --git a/cmd/kes/policy.go b/cmd/kes/policy.go index fbe63703..478c49b9 100644 --- a/cmd/kes/policy.go +++ b/cmd/kes/policy.go @@ -224,10 +224,10 @@ func infoPolicyCmd(args []string) { fmt.Println(faint.Render(fmt.Sprintf("%-11s", "Name")), policyStyle.Render(name)) if !info.CreatedAt.IsZero() { year, month, day := info.CreatedAt.Local().Date() - hour, min, sec := info.CreatedAt.Local().Clock() + hour, minute, sec := info.CreatedAt.Local().Clock() fmt.Println( faint.Render(fmt.Sprintf("%-11s", "Date")), - fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec), + fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, sec), ) } if !info.CreatedBy.IsUnknown() { @@ -335,8 +335,8 @@ func showPolicyCmd(args []string) { header := tui.NewStyle().Bold(true).Foreground(Cyan) if !policy.CreatedAt.IsZero() { year, month, day := policy.CreatedAt.Local().Date() - hour, min, sec := policy.CreatedAt.Local().Clock() - fmt.Printf("\n%s %04d-%02d-%02d %02d:%02d:%02d\n", header.Render("Created at:"), year, month, day, hour, min, sec) + hour, minute, sec := policy.CreatedAt.Local().Clock() + fmt.Printf("\n%s %04d-%02d-%02d %02d:%02d:%02d\n", header.Render("Created at:"), year, month, day, hour, minute, sec) } if !policy.CreatedBy.IsUnknown() { fmt.Println(header.Render("Created by:"), policy.CreatedBy) diff --git a/internal/keystore/vault/client.go b/internal/keystore/vault/client.go index f7ee6f4a..f34aee52 100644 --- a/internal/keystore/vault/client.go +++ b/internal/keystore/vault/client.go @@ -7,7 +7,9 @@ package vault import ( "context" "errors" + "os" "path" + "strings" "sync/atomic" "time" @@ -104,9 +106,18 @@ func (c *client) AuthenticateWithK8S(login *Kubernetes) authFunc { client = client.WithNamespace(login.Namespace) } + jwt := login.JWT + if strings.ContainsRune(jwt, '/') || strings.ContainsRune(jwt, os.PathSeparator) { + jwtBytes, err := os.ReadFile(jwt) + if err != nil { + return nil, err + } + jwt = string(jwtBytes) + } + secret, err := client.Logical().WriteWithContext(ctx, path.Join("auth", login.Engine, "login"), map[string]interface{}{ "role": login.Role, - "jwt": login.JWT, + "jwt": jwt, }) if secret == nil && err == nil { // The Vault SDK eventually returns no error but also no diff --git a/kesconf/config.go b/kesconf/config.go index d9940f43..67860da2 100644 --- a/kesconf/config.go +++ b/kesconf/config.go @@ -447,11 +447,11 @@ func ymlToKeyStore(y *ymlFile) (KeyStore, error) { // We always check for '/' and the OS-specific one make cover cases where // a path is specified using '/' but the underlying OS is e.g. windows. if jwt := y.KeyStore.Vault.Kubernetes.JWT.Value; strings.ContainsRune(jwt, '/') || strings.ContainsRune(jwt, os.PathSeparator) { - b, err := os.ReadFile(y.KeyStore.Vault.Kubernetes.JWT.Value) + _, err := os.ReadFile(y.KeyStore.Vault.Kubernetes.JWT.Value) if err != nil { return nil, fmt.Errorf("kesconf: failed to read vault kubernetes JWT from '%s': %v", y.KeyStore.Vault.Kubernetes.JWT.Value, err) } - y.KeyStore.Vault.Kubernetes.JWT.Value = string(b) + // postpone resolving the JWT until actually logging in } } if y.KeyStore.Vault.Transit != nil { diff --git a/kesconf/config_test.go b/kesconf/config_test.go index b12e4fda..4531a62a 100644 --- a/kesconf/config_test.go +++ b/kesconf/config_test.go @@ -175,7 +175,7 @@ func TestReadServerConfigYAML_VaultWithK8S_JWTFile(t *testing.T) { Prefix = "tenant-2" K8SEngine = "kubernetes" K8SRole = "default" - K8SJWT = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkJQbGNNeTdBeXdLQmZMaGw2N1dFZkJvUmtsdnVvdkxXWGsteTc5TmJPeGMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJteS1uYW1lc3BhY2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoibXktc2VydmljZS1hY2NvdW50LXRva2VuLXA5NWRyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Im15LXNlcnZpY2UtYWNjb3VudCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjdiYmViZGE2LTViMDUtNGFlNC05Yjg2LTBkODE0NWMwNzdhNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpteS1uYW1lc3BhY2U6bXktc2VydmljZS1hY2NvdW50In0.dnvJE3LU7L8XxsIOwea3lUZAULdwAjV9_crHFLKBGNxEu70lk3MQmUbGTEFvawryArmxMa1bWF9wbK1GHEsNipDgWAmc0rmBYByP_ahlf9bI2EEzpaGU5s194csB_eG7kvfi1AHED_nkVTfvCjIJM-9oGICCjDJcoNOP1NAXICFmqvWfXl6SY3UoZvtzUOcH9-0hbARY3p6V5pPecW4Dm-yGub9PKZLJNzv7GxChM-uvBvHAt6o0UBIL4iSy6Bx2l91ojB-RSkm_oy0W9gKi9ZFQPgyvcvQnEfjoGdvNGlOEdFEdXvl-dP6iLBPnZ5xwhAk8lK0oOONWvQg6VDNd9w" + K8SJWTFile = "./testdata/vault-k8s-service-account" ) config, err := ReadFile(Filename) @@ -203,8 +203,8 @@ func TestReadServerConfigYAML_VaultWithK8S_JWTFile(t *testing.T) { if vault.Kubernetes.Engine != K8SEngine { t.Fatalf("Invalid K8S engine: got '%s' - want '%s'", vault.Kubernetes.Engine, K8SEngine) } - if vault.Kubernetes.JWT != K8SJWT { - t.Fatalf("Invalid K8S JWT: got '%s' - want '%s'", vault.Kubernetes.JWT, K8SJWT) + if vault.Kubernetes.JWT != K8SJWTFile { + t.Fatalf("Invalid K8S JWT: got '%s' - want '%s'", vault.Kubernetes.JWT, K8SJWTFile) } if vault.Kubernetes.Role != K8SRole { t.Fatalf("Invalid K8S role: got '%s' - want'%s'", vault.Kubernetes.Role, K8SRole)