From d28d3449de38464abcdb3f3d915f2f1db9077f53 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 1 Aug 2025 21:04:29 +0530 Subject: [PATCH] feat: added ldap authentication to operator --- k8-operator/api/v1alpha1/common.go | 9 +++ .../api/v1alpha1/infisicalsecret_types.go | 11 +++ .../api/v1alpha1/zz_generated.deepcopy.go | 35 ++++++++++ ...infisical.com_infisicaldynamicsecrets.yaml | 21 ++++++ ...ts.infisical.com_infisicalpushsecrets.yaml | 21 ++++++ ...ecrets.infisical.com_infisicalsecrets.yaml | 37 ++++++++++ .../infisicalsecret/infisicalSecretCrd.yaml | 6 ++ .../infisicaldynamicsecret_helper.go | 1 + .../infisicalpushsecret_helper.go | 1 + .../infisicalsecret/infisicalsecret_helper.go | 1 + k8-operator/go.mod | 6 +- k8-operator/go.sum | 14 ++++ k8-operator/packages/model/model.go | 5 ++ k8-operator/packages/util/auth.go | 67 +++++++++++++++++++ k8-operator/packages/util/kubernetes.go | 27 ++++++++ 15 files changed, 261 insertions(+), 1 deletion(-) diff --git a/k8-operator/api/v1alpha1/common.go b/k8-operator/api/v1alpha1/common.go index 2362857d8..ce7a3db3b 100644 --- a/k8-operator/api/v1alpha1/common.go +++ b/k8-operator/api/v1alpha1/common.go @@ -13,6 +13,8 @@ type GenericInfisicalAuthentication struct { GcpIdTokenAuth GenericGcpIdTokenAuth `json:"gcpIdTokenAuth,omitempty"` // +kubebuilder:validation:Optional GcpIamAuth GenericGcpIamAuth `json:"gcpIamAuth,omitempty"` + // +kubebuilder:validation:Optional + LdapAuth GenericLdapAuth `json:"ldapAuth,omitempty"` } type GenericUniversalAuth struct { @@ -20,6 +22,13 @@ type GenericUniversalAuth struct { CredentialsRef KubeSecretReference `json:"credentialsRef"` } +type GenericLdapAuth struct { + // +kubebuilder:validation:Required + IdentityID string `json:"identityId"` + // +kubebuilder:validation:Required + CredentialsRef KubeSecretReference `json:"credentialsRef"` +} + type GenericAwsIamAuth struct { // +kubebuilder:validation:Required IdentityID string `json:"identityId"` diff --git a/k8-operator/api/v1alpha1/infisicalsecret_types.go b/k8-operator/api/v1alpha1/infisicalsecret_types.go index ff26a878c..e4da2911b 100644 --- a/k8-operator/api/v1alpha1/infisicalsecret_types.go +++ b/k8-operator/api/v1alpha1/infisicalsecret_types.go @@ -21,6 +21,8 @@ type Authentication struct { GcpIdTokenAuth GCPIdTokenAuthDetails `json:"gcpIdTokenAuth"` // +kubebuilder:validation:Optional GcpIamAuth GcpIamAuthDetails `json:"gcpIamAuth"` + // +kubebuilder:validation:Optional + LdapAuth LdapAuthDetails `json:"ldapAuth"` } type UniversalAuthDetails struct { @@ -30,6 +32,15 @@ type UniversalAuthDetails struct { SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` } +type LdapAuthDetails struct { + // +kubebuilder:validation:Required + IdentityID string `json:"identityId"` + // +kubebuilder:validation:Required + CredentialsRef KubeSecretReference `json:"credentialsRef"` + // +kubebuilder:validation:Required + SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` +} + type KubernetesAuthDetails struct { // +kubebuilder:validation:Required IdentityID string `json:"identityId"` diff --git a/k8-operator/api/v1alpha1/zz_generated.deepcopy.go b/k8-operator/api/v1alpha1/zz_generated.deepcopy.go index 382b0e8cd..4feafa4b0 100644 --- a/k8-operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/k8-operator/api/v1alpha1/zz_generated.deepcopy.go @@ -53,6 +53,7 @@ func (in *Authentication) DeepCopyInto(out *Authentication) { out.AzureAuth = in.AzureAuth out.GcpIdTokenAuth = in.GcpIdTokenAuth out.GcpIamAuth = in.GcpIamAuth + out.LdapAuth = in.LdapAuth } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication. @@ -326,6 +327,7 @@ func (in *GenericInfisicalAuthentication) DeepCopyInto(out *GenericInfisicalAuth out.AzureAuth = in.AzureAuth out.GcpIdTokenAuth = in.GcpIdTokenAuth out.GcpIamAuth = in.GcpIamAuth + out.LdapAuth = in.LdapAuth } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericInfisicalAuthentication. @@ -359,6 +361,22 @@ func (in *GenericKubernetesAuth) DeepCopy() *GenericKubernetesAuth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericLdapAuth) DeepCopyInto(out *GenericLdapAuth) { + *out = *in + out.CredentialsRef = in.CredentialsRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericLdapAuth. +func (in *GenericLdapAuth) DeepCopy() *GenericLdapAuth { + if in == nil { + return nil + } + out := new(GenericLdapAuth) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GenericUniversalAuth) DeepCopyInto(out *GenericUniversalAuth) { *out = *in @@ -810,6 +828,23 @@ func (in *KubernetesServiceAccountRef) DeepCopy() *KubernetesServiceAccountRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LdapAuthDetails) DeepCopyInto(out *LdapAuthDetails) { + *out = *in + out.CredentialsRef = in.CredentialsRef + out.SecretsScope = in.SecretsScope +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapAuthDetails. +func (in *LdapAuthDetails) DeepCopy() *LdapAuthDetails { + if in == nil { + return nil + } + out := new(LdapAuthDetails) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MachineIdentityScopeInWorkspace) DeepCopyInto(out *MachineIdentityScopeInWorkspace) { *out = *in diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml index 341155efb..2da712186 100644 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml +++ b/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml @@ -103,6 +103,27 @@ spec: - identityId - serviceAccountRef type: object + ldapAuth: + properties: + credentialsRef: + properties: + secretName: + description: The name of the Kubernetes Secret + type: string + secretNamespace: + description: The name space where the Kubernetes Secret + is located + type: string + required: + - secretName + - secretNamespace + type: object + identityId: + type: string + required: + - credentialsRef + - identityId + type: object universalAuth: properties: credentialsRef: diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml index 9d7e2adbd..1fc61e59f 100644 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml +++ b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml @@ -103,6 +103,27 @@ spec: - identityId - serviceAccountRef type: object + ldapAuth: + properties: + credentialsRef: + properties: + secretName: + description: The name of the Kubernetes Secret + type: string + secretNamespace: + description: The name space where the Kubernetes Secret + is located + type: string + required: + - secretName + - secretNamespace + type: object + identityId: + type: string + required: + - credentialsRef + - identityId + type: object universalAuth: properties: credentialsRef: diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml index 8012521d9..87cba3df0 100644 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml +++ b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml @@ -181,6 +181,43 @@ spec: - secretsScope - serviceAccountRef type: object + ldapAuth: + properties: + credentialsRef: + properties: + secretName: + description: The name of the Kubernetes Secret + type: string + secretNamespace: + description: The name space where the Kubernetes Secret + is located + type: string + required: + - secretName + - secretNamespace + type: object + identityId: + type: string + secretsScope: + properties: + envSlug: + type: string + projectSlug: + type: string + recursive: + type: boolean + secretsPath: + type: string + required: + - envSlug + - projectSlug + - secretsPath + type: object + required: + - credentialsRef + - identityId + - secretsScope + type: object serviceAccount: properties: environmentName: diff --git a/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml b/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml index 82bb8039c..1a7a3482d 100644 --- a/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml +++ b/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml @@ -65,6 +65,12 @@ spec: secretsPath: "/path" recursive: true + ldapAuth: + identityId: + credentialsRef: + secretName: # ldap-auth-credentials + secretNamespace: # default + # Azure Auth azureAuth: identityId: diff --git a/k8-operator/controllers/infisicaldynamicsecret/infisicaldynamicsecret_helper.go b/k8-operator/controllers/infisicaldynamicsecret/infisicaldynamicsecret_helper.go index 6e3b135e4..daae2bf9d 100644 --- a/k8-operator/controllers/infisicaldynamicsecret/infisicaldynamicsecret_helper.go +++ b/k8-operator/controllers/infisicaldynamicsecret/infisicaldynamicsecret_helper.go @@ -85,6 +85,7 @@ func (r *InfisicalDynamicSecretReconciler) handleAuthentication(ctx context.Cont util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth, util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth, util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth, + util.AuthStrategy.LDAP_MACHINE_IDENTITY: util.HandleLdapAuth, } for authStrategy, authHandler := range authStrategies { diff --git a/k8-operator/controllers/infisicalpushsecret/infisicalpushsecret_helper.go b/k8-operator/controllers/infisicalpushsecret/infisicalpushsecret_helper.go index 1400b163b..3cd7d21d7 100644 --- a/k8-operator/controllers/infisicalpushsecret/infisicalpushsecret_helper.go +++ b/k8-operator/controllers/infisicalpushsecret/infisicalpushsecret_helper.go @@ -32,6 +32,7 @@ func (r *InfisicalPushSecretReconciler) handleAuthentication(ctx context.Context util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth, util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth, util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth, + util.AuthStrategy.LDAP_MACHINE_IDENTITY: util.HandleLdapAuth, } for authStrategy, authHandler := range authStrategies { diff --git a/k8-operator/controllers/infisicalsecret/infisicalsecret_helper.go b/k8-operator/controllers/infisicalsecret/infisicalsecret_helper.go index f2197b0ed..c443738e1 100644 --- a/k8-operator/controllers/infisicalsecret/infisicalsecret_helper.go +++ b/k8-operator/controllers/infisicalsecret/infisicalsecret_helper.go @@ -57,6 +57,7 @@ func (r *InfisicalSecretReconciler) handleAuthentication(ctx context.Context, in util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth, util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth, util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth, + util.AuthStrategy.LDAP_MACHINE_IDENTITY: util.HandleLdapAuth, } for authStrategy, authHandler := range authStrategies { diff --git a/k8-operator/go.mod b/k8-operator/go.mod index b5de6b278..782059503 100644 --- a/k8-operator/go.mod +++ b/k8-operator/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/Masterminds/sprig/v3 v3.3.0 github.com/aws/smithy-go v1.20.3 - github.com/infisical/go-sdk v0.5.97 + github.com/infisical/go-sdk v0.5.99 github.com/lestrrat-go/jwx/v2 v2.1.4 github.com/onsi/ginkgo/v2 v2.6.0 github.com/onsi/gomega v1.24.1 @@ -40,6 +40,7 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/goccy/go-json v0.10.3 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.5 // indirect @@ -52,9 +53,12 @@ require ( github.com/lestrrat-go/option v1.0.1 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/oracle/oci-go-sdk/v65 v65.95.2 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect + github.com/sony/gobreaker v0.5.0 // indirect github.com/spf13/cast v1.7.0 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect diff --git a/k8-operator/go.sum b/k8-operator/go.sum index a082da41c..a86541adc 100644 --- a/k8-operator/go.sum +++ b/k8-operator/go.sum @@ -152,6 +152,8 @@ github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -237,6 +239,8 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/infisical/go-sdk v0.5.97 h1:veOi6Hduda6emtwjdUI5SBg2qd2iDQc5xLKqZ15KSoM= github.com/infisical/go-sdk v0.5.97/go.mod h1:ExjqFLRz7LSpZpGluqDLvFl6dFBLq5LKyLW7GBaMAIs= +github.com/infisical/go-sdk v0.5.99 h1:trvn7JhKYuSzDkc44h+yqToVjclkrRyP42t315k5kEE= +github.com/infisical/go-sdk v0.5.99/go.mod h1:j2D2a5WPNdKXDfHO+3y/TNyLWh5Aq9QYS7EcGI96LZI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -303,6 +307,8 @@ github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/oracle/oci-go-sdk/v65 v65.95.2 h1:0HJ0AgpLydp/DtvYrF2d4str2BjXOVAeNbuW7E07g94= +github.com/oracle/oci-go-sdk/v65 v65.95.2/go.mod h1:u6XRPsw9tPziBh76K7GrrRXPa8P8W3BQeqJ6ZZt9VLA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -347,6 +353,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= +github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -365,8 +373,11 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -407,6 +418,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= @@ -551,6 +563,7 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -559,6 +572,7 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= diff --git a/k8-operator/packages/model/model.go b/k8-operator/packages/model/model.go index 3b3bc3216..3e8577be4 100644 --- a/k8-operator/packages/model/model.go +++ b/k8-operator/packages/model/model.go @@ -11,6 +11,11 @@ type MachineIdentityDetails struct { ClientSecret string } +type LdapIdentityDetails struct { + Username string + Password string +} + type SingleEnvironmentVariable struct { Key string `json:"key"` Value string `json:"value"` diff --git a/k8-operator/packages/util/auth.go b/k8-operator/packages/util/auth.go index 7305ca45e..f3512027e 100644 --- a/k8-operator/packages/util/auth.go +++ b/k8-operator/packages/util/auth.go @@ -88,6 +88,7 @@ var AuthStrategy = struct { AZURE_MACHINE_IDENTITY AuthStrategyType GCP_ID_TOKEN_MACHINE_IDENTITY AuthStrategyType GCP_IAM_MACHINE_IDENTITY AuthStrategyType + LDAP_MACHINE_IDENTITY AuthStrategyType }{ SERVICE_TOKEN: "SERVICE_TOKEN", SERVICE_ACCOUNT: "SERVICE_ACCOUNT", @@ -97,6 +98,7 @@ var AuthStrategy = struct { AZURE_MACHINE_IDENTITY: "AZURE_MACHINE_IDENTITY", GCP_ID_TOKEN_MACHINE_IDENTITY: "GCP_ID_TOKEN_MACHINE_IDENTITY", GCP_IAM_MACHINE_IDENTITY: "GCP_IAM_MACHINE_IDENTITY", + LDAP_MACHINE_IDENTITY: "LDAP_MACHINE_IDENTITY", } type SecretCrdType string @@ -188,6 +190,71 @@ func HandleUniversalAuth(ctx context.Context, reconcilerClient client.Client, se }, nil } +func HandleLdapAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface) (AuthenticationDetails, error) { + + var ldapAuthSpec v1alpha1.LdapAuthDetails + + switch secretCrd.Type { + case SecretCrd.INFISICAL_SECRET: + infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) + + if !ok { + return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") + } + ldapAuthSpec = infisicalSecret.Spec.Authentication.LdapAuth + case SecretCrd.INFISICAL_PUSH_SECRET: + infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) + + if !ok { + return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") + } + + ldapAuthSpec = v1alpha1.LdapAuthDetails{ + CredentialsRef: infisicalPushSecret.Spec.Authentication.LdapAuth.CredentialsRef, + SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, + IdentityID: infisicalPushSecret.Spec.Authentication.LdapAuth.IdentityID, + } + + case SecretCrd.INFISICAL_DYNAMIC_SECRET: + infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) + + if !ok { + return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") + } + + ldapAuthSpec = v1alpha1.LdapAuthDetails{ + CredentialsRef: infisicalDynamicSecret.Spec.Authentication.UniversalAuth.CredentialsRef, + SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, + IdentityID: infisicalDynamicSecret.Spec.Authentication.LdapAuth.IdentityID, + } + } + + ldapAuthKubeSecret, err := GetInfisicalLdapAuthFromKubeSecret(ctx, reconcilerClient, v1alpha1.KubeSecretReference{ + SecretNamespace: ldapAuthSpec.CredentialsRef.SecretNamespace, + SecretName: ldapAuthSpec.CredentialsRef.SecretName, + }) + + if err != nil { + return AuthenticationDetails{}, fmt.Errorf("ReconcileInfisicalSecret: unable to get machine identity creds from kube secret [err=%s]", err) + } + + if ldapAuthKubeSecret.Username == "" && ldapAuthKubeSecret.Password == "" { + return AuthenticationDetails{}, ErrAuthNotApplicable + } + + _, err = infisicalClient.Auth().LdapAuthLogin(ldapAuthSpec.IdentityID, ldapAuthKubeSecret.Username, ldapAuthKubeSecret.Password) + if err != nil { + return AuthenticationDetails{}, fmt.Errorf("unable to login with machine identity credentials [err=%s]", err) + } + + return AuthenticationDetails{ + AuthStrategy: AuthStrategy.LDAP_MACHINE_IDENTITY, + MachineIdentityScope: ldapAuthSpec.SecretsScope, + IsMachineIdentityAuth: true, + SecretType: secretCrd.Type, + }, nil +} + func HandleKubernetesAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface) (AuthenticationDetails, error) { var kubernetesAuthSpec v1alpha1.KubernetesAuthDetails diff --git a/k8-operator/packages/util/kubernetes.go b/k8-operator/packages/util/kubernetes.go index b11c0a623..ac5e27bdf 100644 --- a/k8-operator/packages/util/kubernetes.go +++ b/k8-operator/packages/util/kubernetes.go @@ -18,6 +18,9 @@ import ( const INFISICAL_MACHINE_IDENTITY_CLIENT_ID = "clientId" const INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET = "clientSecret" +const INFISICAL_MACHINE_IDENTITY_LDAP_USERNAME = "username" +const INFISICAL_MACHINE_IDENTITY_LDAP_PASSSWORD = "password" + func GetKubeSecretByNamespacedName(ctx context.Context, reconcilerClient client.Client, namespacedName types.NamespacedName) (*corev1.Secret, error) { kubeSecret := &corev1.Secret{} err := reconcilerClient.Get(ctx, namespacedName, kubeSecret) @@ -62,6 +65,30 @@ func GetInfisicalUniversalAuthFromKubeSecret(ctx context.Context, reconcilerClie } +func GetInfisicalLdapAuthFromKubeSecret(ctx context.Context, reconcilerClient client.Client, ldapAuthRef v1alpha1.KubeSecretReference) (machineIdentityDetails model.LdapIdentityDetails, err error) { + + ldapAuthCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{ + Namespace: ldapAuthRef.SecretNamespace, + Name: ldapAuthRef.SecretName, + // Namespace: infisicalSecret.Spec.Authentication.UniversalAuth.CredentialsRef.SecretNamespace, + // Name: infisicalSecret.Spec.Authentication.UniversalAuth.CredentialsRef.SecretName, + }) + + if k8Errors.IsNotFound(err) { + return model.LdapIdentityDetails{}, nil + } + + if err != nil { + return model.LdapIdentityDetails{}, fmt.Errorf("something went wrong when fetching your machine identity credentials [err=%s]", err) + } + + usernameFromSecret := ldapAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_LDAP_USERNAME] + passwordFromSecret := ldapAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_LDAP_PASSSWORD] + + return model.LdapIdentityDetails{Username: string(usernameFromSecret), Password: string(passwordFromSecret)}, nil + +} + func getKubeClusterConfig() (*rest.Config, error) { config, err := rest.InClusterConfig() if err != nil {