Files
oikos/vendor/github.com/infisical/go-sdk/auth.go
dtoro febc153b7f
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
fix: add involves edge from task to agent:nomos at creation
Plus sync vendor directory for Docker build compatibility.
2026-08-11 22:03:12 +02:00

538 lines
16 KiB
Go

package infisical
import (
"context"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"strings"
"time"
api "github.com/infisical/go-sdk/packages/api/auth"
"github.com/infisical/go-sdk/packages/models"
"github.com/infisical/go-sdk/packages/util"
"github.com/oracle/oci-go-sdk/v65/common"
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
)
type KubernetesAuthLoginOptions struct {
IdentityID string
ServiceAccountTokenPath string
}
type AuthInterface interface {
SetAccessToken(accessToken string)
GetAccessToken() string
GetOrganizationSlug() string
// When set, this will scope the login session to the specified sub-organization the machine identity has access to. If left empty, the session defaults to the organization where the machine identity was created in.
WithOrganizationSlug(organizationSlug string) AuthInterface
// When set, the next AzureAuthLogin call will request a token for the specified User-Assigned Managed Identity (UAMI) by its client ID. Leave unset for System-Assigned Managed Identity.
WithAzureClientID(clientID string) AuthInterface
UniversalAuthLogin(clientID string, clientSecret string) (credential MachineIdentityCredential, err error)
JwtAuthLogin(identityID string, jwt string) (credential MachineIdentityCredential, err error)
KubernetesAuthLogin(identityID string, serviceAccountTokenPath string) (credential MachineIdentityCredential, err error)
KubernetesRawServiceAccountTokenLogin(identityID string, serviceAccountToken string) (credential MachineIdentityCredential, err error)
AzureAuthLogin(identityID string, resource string) (credential MachineIdentityCredential, err error)
GcpIdTokenAuthLogin(identityID string) (credential MachineIdentityCredential, err error)
GcpIamAuthLogin(identityID string, serviceAccountKeyFilePath string) (credential MachineIdentityCredential, err error)
AwsIamAuthLogin(identityId string) (credential MachineIdentityCredential, err error)
OidcAuthLogin(identityId string, jwt string) (credential MachineIdentityCredential, err error)
OciAuthLogin(options OciAuthLoginOptions) (credential MachineIdentityCredential, err error)
LdapAuthLogin(identityID string, username string, password string) (credential MachineIdentityCredential, err error)
RevokeAccessToken() error
}
type Auth struct {
client *InfisicalClient
organizationSlug string
azureClientID string
}
func (a *Auth) SetAccessToken(accessToken string) {
a.client.setPlainAccessToken(accessToken)
}
func (a *Auth) GetOrganizationSlug() string {
return a.organizationSlug
}
func (a *Auth) WithOrganizationSlug(organizationSlug string) AuthInterface {
a.organizationSlug = organizationSlug
return a
}
func (a *Auth) WithAzureClientID(clientID string) AuthInterface {
a.azureClientID = clientID
return a
}
func (a *Auth) GetAccessToken() string {
// case: user has set an access token manually, so we get it directly from the credential
if a.client.authMethod == util.ACCESS_TOKEN {
if parsedCreds, ok := a.client.credential.(models.AccessTokenCredential); ok {
return parsedCreds.AccessToken
}
return ""
}
return a.client.tokenDetails.AccessToken
}
func (a *Auth) RevokeAccessToken() error {
if a.client.tokenDetails.AccessToken == "" {
return errors.New("sdk client is not authenticated, cannot revoke access token")
}
_, err := api.CallRevokeAccessToken(a.client.httpClient, api.RevokeAccessTokenRequest{
AccessToken: a.client.tokenDetails.AccessToken,
})
if err != nil {
return err
}
a.client.clearAccessToken()
return nil
}
func (a *Auth) UniversalAuthLogin(clientID string, clientSecret string) (credential MachineIdentityCredential, err error) {
if clientID == "" {
clientID = os.Getenv(util.INFISICAL_UNIVERSAL_AUTH_CLIENT_ID_ENV_NAME)
}
if clientSecret == "" {
clientSecret = os.Getenv(util.INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallUniversalAuthLogin(a.client.httpClient, api.UniversalAuthLoginRequest{
ClientID: clientID,
ClientSecret: clientSecret,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.UniversalAuthCredential{ClientID: clientID, ClientSecret: clientSecret},
util.UNIVERSAL_AUTH,
)
return credential, nil
}
func (a *Auth) KubernetesAuthLogin(identityID string, serviceAccountTokenPath string) (credential MachineIdentityCredential, err error) {
if serviceAccountTokenPath == "" {
serviceAccountTokenPath = os.Getenv(util.DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH)
}
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
serviceAccountToken, serviceAccountTokenErr := util.GetKubernetesServiceAccountToken(serviceAccountTokenPath)
if serviceAccountTokenErr != nil {
return MachineIdentityCredential{}, serviceAccountTokenErr
}
credential, err = api.CallKubernetesAuthLogin(a.client.httpClient, api.KubernetesAuthLoginRequest{
IdentityID: identityID,
JWT: serviceAccountToken,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.KubernetesCredential{IdentityID: identityID, ServiceAccountToken: serviceAccountToken},
util.KUBERNETES,
)
return credential, nil
}
func (a *Auth) KubernetesRawServiceAccountTokenLogin(identityID string, serviceAccountToken string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallKubernetesAuthLogin(a.client.httpClient, api.KubernetesAuthLoginRequest{
IdentityID: identityID,
JWT: serviceAccountToken,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.KubernetesCredential{IdentityID: identityID, ServiceAccountToken: serviceAccountToken},
util.KUBERNETES,
)
return credential, nil
}
func (a *Auth) AzureAuthLogin(identityID string, resource string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_AZURE_AUTH_IDENTITY_ID_ENV_NAME)
}
clientID := a.azureClientID
if clientID == "" {
clientID = os.Getenv(util.INFISICAL_AZURE_AUTH_CLIENT_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
jwt, jwtError := util.GetAzureMetadataToken(a.client.httpClient, resource, clientID)
if jwtError != nil {
return MachineIdentityCredential{}, jwtError
}
credential, err = api.CallAzureAuthLogin(a.client.httpClient, api.AzureAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.AzureCredential{IdentityID: identityID, Resource: resource, ClientID: clientID},
util.AZURE,
)
return credential, nil
}
func (a *Auth) GcpIdTokenAuthLogin(identityID string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
jwt, jwtError := util.GetGCPMetadataToken(a.client.httpClient, identityID)
if jwtError != nil {
return MachineIdentityCredential{}, jwtError
}
credential, err = api.CallGCPAuthLogin(a.client.httpClient, api.GCPAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.GCPIDTokenCredential{IdentityID: identityID},
util.GCP_ID_TOKEN,
)
return credential, nil
}
func (a *Auth) GcpIamAuthLogin(identityID string, serviceAccountKeyFilePath string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME)
}
if serviceAccountKeyFilePath == "" {
serviceAccountKeyFilePath = os.Getenv(util.INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
jwt, jwtError := util.GetGCPIamServiceAccountToken(identityID, serviceAccountKeyFilePath)
if jwtError != nil {
return MachineIdentityCredential{}, jwtError
}
credential, err = api.CallGCPAuthLogin(a.client.httpClient, api.GCPAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.GCPIAMCredential{IdentityID: identityID, ServiceAccountKeyFilePath: serviceAccountKeyFilePath},
util.GCP_IAM,
)
return credential, nil
}
func (a *Auth) AwsIamAuthLogin(identityId string) (credential MachineIdentityCredential, err error) {
if identityId == "" {
identityId = os.Getenv(util.INFISICAL_AWS_IAM_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
awsCredentials, awsRegion, err := util.RetrieveAwsCredentials()
if err != nil {
return MachineIdentityCredential{}, err
}
// Prepare request for signing
iamRequestURL := fmt.Sprintf("https://sts.%s.amazonaws.com/", awsRegion)
iamRequestBody := "Action=GetCallerIdentity&Version=2011-06-15"
req, err := http.NewRequest(http.MethodPost, iamRequestURL, strings.NewReader(iamRequestBody))
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("error creating HTTP request: %v", err)
}
currentTime := time.Now().UTC()
req.Header.Add("X-Amz-Date", currentTime.Format("20060102T150405Z"))
hashGenerator := sha256.New()
hashGenerator.Write([]byte(iamRequestBody))
payloadHash := fmt.Sprintf("%x", hashGenerator.Sum(nil))
signer := v4.NewSigner()
err = signer.SignHTTP(context.TODO(), awsCredentials, req, payloadHash, "sts", awsRegion, time.Now())
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("error signing request: %v", err)
}
realHeaders := make(map[string]string)
for name, values := range req.Header {
if strings.ToLower(name) == "content-length" {
continue
}
realHeaders[name] = values[0]
}
realHeaders["Host"] = fmt.Sprintf("sts.%s.amazonaws.com", awsRegion)
realHeaders["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8"
realHeaders["Content-Length"] = fmt.Sprintf("%d", len(iamRequestBody))
// convert the headers to a json marshalled string
jsonStringHeaders, err := json.Marshal(realHeaders)
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("error marshalling headers: %v", err)
}
credential, tokenErr := api.CallAWSIamAuthLogin(a.client.httpClient, api.AwsIamAuthLoginRequest{
HTTPRequestMethod: req.Method,
// Encoding is intended, we decode it on severside, and I know everything happening on the server is being done correctly. So it's something broken in this code somewhere.
IamRequestBody: base64.StdEncoding.EncodeToString([]byte(iamRequestBody)),
IamRequestHeaders: base64.StdEncoding.EncodeToString(jsonStringHeaders),
IdentityId: identityId,
OrganizationSlug: organizationSlug,
})
if tokenErr != nil {
return MachineIdentityCredential{}, tokenErr
}
a.client.setAccessToken(
credential,
models.AWSIAMCredential{IdentityID: identityId},
util.AWS_IAM,
)
return credential, nil
}
func (a *Auth) OidcAuthLogin(identityId string, jwt string) (credential MachineIdentityCredential, err error) {
if identityId == "" {
identityId = os.Getenv(util.INFISICAL_OIDC_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallOidcAuthLogin(a.client.httpClient, api.OidcAuthLoginRequest{
IdentityID: identityId,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.OIDCCredential{IdentityID: identityId},
util.OIDC_AUTH,
)
return credential, nil
}
func (a *Auth) JwtAuthLogin(identityID string, jwt string) (credential MachineIdentityCredential, err error) {
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallJwtAuthLogin(a.client.httpClient, api.JwtAuthLoginRequest{
IdentityID: identityID,
JWT: jwt,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.JWTCredential{IdentityID: identityID, JWT: jwt},
util.JWT_AUTH,
)
return credential, nil
}
func (a *Auth) OciAuthLogin(options OciAuthLoginOptions) (credential MachineIdentityCredential, err error) {
if options.IdentityID == "" {
options.IdentityID = os.Getenv(util.INFISICAL_OCI_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
provider := common.NewRawConfigurationProvider(
options.TenancyID,
options.UserID,
options.Region,
options.Fingerprint,
options.PrivateKey,
options.Passphrase,
)
requestURL := fmt.Sprintf("https://identity.%s.oraclecloud.com/20160918/users/%s", options.Region, options.UserID)
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("OciAuthLogin: failed to create request: %w", err)
}
req.Header.Set("host", fmt.Sprintf("identity.%s.oraclecloud.com", options.Region))
req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
signer := common.DefaultRequestSigner(provider)
err = signer.Sign(req)
if err != nil {
return MachineIdentityCredential{}, fmt.Errorf("OciAuthLogin: failed to sign request: %w", err)
}
headersMap := make(map[string]string)
for name, values := range req.Header {
if len(values) > 0 {
// Convert header names to lowercase to match OCI signature expectations
lowerName := strings.ToLower(name)
headersMap[lowerName] = values[0]
}
}
credential, err = api.CallOciAuthLogin(a.client.httpClient, api.OciAuthLoginRequest{
IdentityID: options.IdentityID,
UserOcid: options.UserID,
Headers: headersMap,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.OCICredential{
IdentityID: options.IdentityID,
PrivateKey: options.PrivateKey,
Fingerprint: options.Fingerprint,
UserID: options.UserID,
TenancyID: options.TenancyID,
Region: options.Region,
Passphrase: options.Passphrase,
},
util.OCI_AUTH,
)
return credential, nil
}
func (a *Auth) LdapAuthLogin(identityID string, username string, password string) (credential MachineIdentityCredential, err error) {
if identityID == "" {
identityID = os.Getenv(util.INFISICAL_LDAP_AUTH_IDENTITY_ID_ENV_NAME)
}
organizationSlug := a.organizationSlug
if organizationSlug == "" {
organizationSlug = os.Getenv(util.INFISICAL_AUTH_ORGANIZATION_SLUG_ENV_NAME)
}
credential, err = api.CallLdapAuthLogin(a.client.httpClient, api.LdapAuthLoginRequest{
IdentityID: identityID,
Username: username,
Password: password,
OrganizationSlug: organizationSlug,
})
if err != nil {
return MachineIdentityCredential{}, err
}
a.client.setAccessToken(
credential,
models.LDAPCredential{IdentityID: identityID, Username: username, Password: password},
util.LDAP_AUTH,
)
return credential, nil
}
func NewAuth(client *InfisicalClient) AuthInterface {
return &Auth{client: client}
}