-
Notifications
You must be signed in to change notification settings - Fork 0
nhi: emit SecretTrait credential type on Kubernetes secrets #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,13 +25,27 @@ const ( | |
| ResourceTypeRoleBinding = "rolebinding" | ||
| SubjectTypeGroup = "Group" | ||
| SubjectTypeUser = "User" | ||
|
|
||
| // Standard Kubernetes object-metadata keys used in resource profiles. | ||
| metadataKeyName = "name" | ||
| metadataKeyNamespace = "namespace" | ||
| metadataKeyUID = "uid" | ||
| metadataKeyCreationTimestamp = "creationTimestamp" | ||
| metadataKeyLabels = "labels" | ||
| metadataKeyAnnotations = "annotations" | ||
|
|
||
| // verbGet is the Kubernetes "get" RBAC verb. | ||
| verbGet = "get" | ||
|
|
||
| // kindRole is the RBAC RoleRef kind for namespaced Roles. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Suggestion: |
||
| kindRole = "Role" | ||
| ) | ||
|
|
||
| // Resource type definitions. | ||
| var ( | ||
| ResourceTypeNamespace = &v2.ResourceType{Id: "namespace", DisplayName: "Namespace"} | ||
| ResourceTypeServiceAccount = &v2.ResourceType{Id: "service_account", DisplayName: "Service Account", Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_USER}} | ||
| ResourceTypeRole = &v2.ResourceType{Id: "role", DisplayName: "Role", Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_ROLE}} | ||
| ResourceTypeRole = &v2.ResourceType{Id: "role", DisplayName: kindRole, Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_ROLE}} | ||
| ResourceTypeClusterRole = &v2.ResourceType{Id: "cluster_role", DisplayName: "Cluster Role", Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_ROLE}} | ||
| ResourceTypeSecret = &v2.ResourceType{Id: "secret", DisplayName: "Secret", Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_SECRET}} | ||
| ResourceTypeConfigMap = &v2.ResourceType{Id: "configmap", DisplayName: "Config Map"} | ||
|
|
@@ -348,7 +362,7 @@ func (k *Kubernetes) GetMatchingRoleBindings(ctx context.Context, namespace, rol | |
|
|
||
| var result []rbacv1.RoleBinding | ||
| for _, binding := range k.roleBindingsCache { | ||
| if binding.Namespace == namespace && binding.RoleRef.Kind == "Role" && binding.RoleRef.Name == roleName { | ||
| if binding.Namespace == namespace && binding.RoleRef.Kind == kindRole && binding.RoleRef.Name == roleName { | ||
| result = append(result, binding) | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| package connector | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" | ||
| "github.com/stretchr/testify/assert" | ||
| corev1 "k8s.io/api/core/v1" | ||
| ) | ||
|
|
||
| // TestSecretCredentialType verifies the Kubernetes secret type -> NHI spine | ||
| // CredentialType + axis-2 detail mapping. | ||
| func TestSecretCredentialType(t *testing.T) { | ||
| testCases := []struct { | ||
| name string | ||
| secretType corev1.SecretType | ||
| wantType v2.SecretTrait_CredentialType | ||
| wantDetail string | ||
| }{ | ||
| { | ||
| name: "service account token", | ||
| secretType: corev1.SecretTypeServiceAccountToken, | ||
| wantType: v2.SecretTrait_CREDENTIAL_TYPE_STATIC_SECRET, | ||
| wantDetail: "k8s.secret.service_account_token", | ||
| }, | ||
| { | ||
| name: "tls is a certificate", | ||
| secretType: corev1.SecretTypeTLS, | ||
| wantType: v2.SecretTrait_CREDENTIAL_TYPE_CERTIFICATE, | ||
| wantDetail: "k8s.secret.tls", | ||
| }, | ||
| { | ||
| name: "ssh auth is an asymmetric key", | ||
| secretType: corev1.SecretTypeSSHAuth, | ||
| wantType: v2.SecretTrait_CREDENTIAL_TYPE_ASYMMETRIC_KEY, | ||
| wantDetail: "k8s.secret.ssh_auth", | ||
| }, | ||
| { | ||
| name: "opaque is a static secret", | ||
| secretType: corev1.SecretTypeOpaque, | ||
| wantType: v2.SecretTrait_CREDENTIAL_TYPE_STATIC_SECRET, | ||
| wantDetail: "k8s.secret.opaque", | ||
| }, | ||
| { | ||
| name: "basic auth is a static secret", | ||
| secretType: corev1.SecretTypeBasicAuth, | ||
| wantType: v2.SecretTrait_CREDENTIAL_TYPE_STATIC_SECRET, | ||
| wantDetail: "k8s.secret.basic_auth", | ||
| }, | ||
| { | ||
| name: "empty type defaults to opaque", | ||
| secretType: corev1.SecretType(""), | ||
| wantType: v2.SecretTrait_CREDENTIAL_TYPE_STATIC_SECRET, | ||
| wantDetail: "k8s.secret.opaque", | ||
| }, | ||
| } | ||
|
|
||
| for _, tc := range testCases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| gotType, gotDetail := secretCredentialType(tc.secretType) | ||
| assert.Equal(t, tc.wantType, gotType) | ||
| assert.Equal(t, tc.wantDetail, gotDetail) | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Suggestion:
SubjectTypeGroupandSubjectTypeUserare now unused — the code was migrated toSubjectKindGroup/SubjectKindUserfromhelper.go. These can be removed to avoid confusion about which constants to use.