SoXX 14944f708f feat: Add OAuth2 client credentials workflow for Vault integration
Introduced OAuth2 client credentials to fetch JWT tokens and updated Vault logic to support authentication with JWT. Modified the main application flow to utilize the new token-based authentication for enhanced security and flexibility. Updated dependencies to include `golang.org/x/oauth2`.

I KNOW THAT I LEAKED THE KEY AND STUFF!
2024-12-21 21:51:24 +01:00

137 lines
3.6 KiB
Go

package vault
import (
"context"
"fmt"
"golang.org/x/oauth2/clientcredentials"
"time"
"github.com/hashicorp/vault-client-go"
"github.com/hashicorp/vault-client-go/schema"
log "github.com/sirupsen/logrus"
)
// GetJWTToken fetches the raw token using client credentials and returns the access token as a string.
func GetJWTToken(clientID string, clientSecret string, tokenURL string) string {
ctx := context.Background()
clientCredsConfig := clientcredentials.Config{
ClientID: clientID,
ClientSecret: clientSecret,
TokenURL: tokenURL,
}
// Fetch the token using the client credentials
token, err := clientCredsConfig.TokenSource(ctx).Token()
if err != nil {
fmt.Printf("Error getting token: %v\n", err)
return ""
}
// Return the raw access token
return token.AccessToken
}
func VaultWithJWT(ctx context.Context, roles string, jwt string) {
// prepare a client with the given base address
client, err := vault.New(
vault.WithAddress("http://localhost:8200"),
vault.WithRequestTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
request := schema.JwtLoginRequest{
Jwt: jwt,
Role: roles,
}
resp, err := client.Auth.JwtLogin(ctx, request)
if err != nil {
log.Fatal(resp, err)
}
err = client.SetToken(resp.Auth.ClientToken)
if err != nil {
log.Fatal(err)
}
}
func VaultWithToken() {
// prepare a client with the given base address
client, err := vault.New(
vault.WithAddress("http://localhost:8200"),
vault.WithRequestTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
//client.SetRequestCallbacks(func(req *http.Request) {
// log.Println("REQUEST:", *req.URL)
//})
// authenticate with a root token (insecure)
if err := client.SetToken("hvs.XD2NNAznvWucjo7B8RhtXpQZ"); err != nil {
log.Fatal(err)
}
}
// WritingAPIKeyToVault writes the API key to a Vault using the given secret data.
//
// The function converts the secret data into a map and writes it to the Vault.
// If any error occurs during this process, it returns the error.
//
// Parameters:
// - ctx: The context for the operation.
// - client: The Vault client used to perform the write operation.
// - secretData: The secret data to be written to the Vault.
//
// Returns an error if the operation fails.
func WritingAPIKeyToVault[T SecretDataTypes](ctx context.Context, client *vault.Client, secretData SecretData[T]) error {
secret, err := SecretToMap(secretData)
if err != nil {
return err
}
request := schema.KvV2WriteRequest{
Data: secret,
}
_, err = client.Secrets.KvV2Write(ctx, secretData.UserSourceID, request, vault.WithMountPath(secretData.Secret.GetMountPath()))
if err != nil {
log.Fatal(err)
}
return nil
}
// ReadingApiKeyFromVault reads the API key from a Vault and populates the given secret data.
//
// The function reads the data from the Vault, converts it back into the appropriate secret type,
// and assigns it to the provided secret data structure.
// If any error occurs during this process, it returns the error.
//
// Parameters:
// - ctx: The context for the operation.
// - client: The Vault client used to perform the read operation.
// - secretData: A pointer to the secret data structure to be populated with the read data.
//
// Returns an error if the operation fails.
func ReadingApiKeyFromVault[T SecretDataTypes](ctx context.Context, client *vault.Client, secretData *SecretData[T]) error {
data, err := client.Secrets.KvV2Read(ctx, secretData.UserSourceID, vault.WithMountPath(secretData.Secret.GetMountPath()))
if err != nil {
log.Fatal(err)
}
secret, err := MapToSecret[T](data.Data.Data)
if err != nil {
return err
}
secretData.Secret = secret
return nil
}