Skip to content

Commit

Permalink
webhook: create sa tokens via apiserver (bank-vaults#1752)
Browse files Browse the repository at this point in the history
Currently the webhook tries to find sa.secrets[0]
and load its token. But this is no longer available
from K8S 1.24 (unless users force creating legacy
tokens on each sa which is not best practice). This
change allows creating tokens by calling the apiserver
instead of expecting it to be available as a k8s
secret associated to the service account.

* webhook: create sa tokens via apiserver
  • Loading branch information
bramaq authored Jan 10, 2023
1 parent 6673167 commit d9b8109
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions pkg/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/slok/kubewebhook/v2/pkg/log"
"github.com/slok/kubewebhook/v2/pkg/model"
"github.com/slok/kubewebhook/v2/pkg/webhook/mutating"
authenticationv1 "k8s.io/api/authentication/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -213,9 +214,34 @@ func (mw *MutatingWebhook) newVaultClient(vaultConfig VaultConfig) (*vault.Clien
return nil, errors.Wrap(err, "Failed to retrieve specified service account on namespace "+vaultConfig.ObjectNamespace)
}

secret, err := mw.k8sClient.CoreV1().Secrets(vaultConfig.ObjectNamespace).Get(context.Background(), sa.Secrets[0].Name, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrap(err, "Failed to retrieve secret for service account "+sa.Secrets[0].Name+" in namespace "+vaultConfig.ObjectNamespace)
saToken := ""
if len(sa.Secrets) > 0 {
secret, err := mw.k8sClient.CoreV1().Secrets(vaultConfig.ObjectNamespace).Get(context.Background(), sa.Secrets[0].Name, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrap(err, "Failed to retrieve secret for service account "+sa.Secrets[0].Name+" in namespace "+vaultConfig.ObjectNamespace)
}
saToken = string(secret.Data["token"])
}

if saToken == "" {
tokenTTL := int64(600) // min allowed duration is 10 mins
tokenRequest := &authenticationv1.TokenRequest{
Spec: authenticationv1.TokenRequestSpec{
Audiences: []string{"https://kubernetes.default.svc"},
ExpirationSeconds: &tokenTTL,
},
}

token, err := mw.k8sClient.CoreV1().ServiceAccounts(vaultConfig.ObjectNamespace).CreateToken(
context.Background(),
vaultConfig.VaultServiceAccount,
tokenRequest,
metav1.CreateOptions{},
)
if err != nil {
return nil, errors.Wrap(err, "Failed to create a token for the specified service account "+vaultConfig.VaultServiceAccount+" on namespace "+vaultConfig.ObjectNamespace)
}
saToken = token.Status.Token
}

return vault.NewClientFromConfig(
Expand All @@ -224,7 +250,7 @@ func (mw *MutatingWebhook) newVaultClient(vaultConfig VaultConfig) (*vault.Clien
vault.ClientAuthPath(vaultConfig.Path),
vault.NamespacedSecretAuthMethod,
vault.ClientLogger(logrusadapter.NewFromEntry(mw.logger)),
vault.ExistingSecret(secret.Data["token"]),
vault.ExistingSecret(saToken),
vault.VaultNamespace(vaultConfig.VaultNamespace),
)
}
Expand Down

0 comments on commit d9b8109

Please sign in to comment.