Skip to content

Commit

Permalink
parse service account name from JWT
Browse files Browse the repository at this point in the history
  • Loading branch information
JayBeale committed Sep 4, 2023
1 parent 00a0e98 commit 9475537
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
24 changes: 10 additions & 14 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,15 @@ func ImportPodServiceAccountToken() ServerInfo {
if errRead == nil {
configInfoVars.Token = string(token)
fmt.Println("Read a service account token from " + tokenFile)
// Name the token for its hostname / pod
configInfoVars.TokenName = "Pod ns:" + configInfoVars.Namespace + ":" + os.Getenv("HOSTNAME")

// Try naming the service account token with its JWT name
_, name := parseServiceAccountJWT(configInfoVars.Token)
if name != "" {
configInfoVars.TokenName = name
} else {
// otherwise, name the token for its hostname / pod
configInfoVars.TokenName = "Pod ns:" + configInfoVars.Namespace + ":" + os.Getenv("HOSTNAME")
}
}

// Reading namespace file and store in variable namespace
Expand Down Expand Up @@ -464,19 +471,8 @@ func gatherPodCredentials(serviceAccounts *[]ServiceAccount, interactive bool, r
}
token := string(tokenBytes)

// If possible, name the token for the namespace
namespacePath := serviceAccountPath + saDirName + "/namespace"
if _, err := os.Stat(namespacePath); os.IsNotExist(err) {
continue
}
namespaceBytes, err := ioutil.ReadFile(namespacePath)
if err != nil {
continue
}
namespace := string(namespaceBytes)

_, tokenName := parseServiceAccountJWT(token)
fullSAName := "short-lived-sa/" + namespace + "/" + tokenName
fullSAName := "short-lived-sa/" + tokenName

// FEATURE REQUEST: spell out which node this was found on in the last arg.
if AddNewServiceAccount(fullSAName, string(token), "pod service account token harvested from node ", serviceAccounts) {
Expand Down
36 changes: 30 additions & 6 deletions service_account_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,34 @@ func parseServiceAccountJWT(tokenString string) (int64, string) {
}
expiration := int64(claims["exp"].(float64))

// Parse out the name of the service account
level1 := claims["kubernetes.io"].(map[string]interface{})
level2 := level1["serviceaccount"].(map[string]interface{})
name := level2["name"].(string)

return expiration, name
// Parse out the name of the service account.
// Here's what a sample JWT looks like:
// {
// "aud": ["https://kubernetes.default.svc.cluster.local"],
// "exp": 1725391365,
// "iat": 1693855365,
// "iss": "https://kubernetes.default.svc.cluster.local",
// "kubernetes.io": {
// "namespace": "default",
// "pod": {
// "name": "web",
// "uid": "..."
// },
// "serviceaccount": {
// "name": "default",
// "uid": "..."
// },
// "warnafter": 1693858972
// },
// "nbf": 1693855365,
// "sub": "system:serviceaccount:default:default"
// }

kubernetesIOstruct := claims["kubernetes.io"].(map[string]interface{})
namespace := kubernetesIOstruct["namespace"].(string)

saStruct := kubernetesIOstruct["serviceaccount"].(map[string]interface{})
name := saStruct["name"].(string)

return expiration, namespace + ":" + name
}

0 comments on commit 9475537

Please sign in to comment.