Documentation
¶
Index ¶
- func BuildNormalizedPolicyRulesMap(rules []rbacv1.PolicyRule, opts *PolicyRuleNormalizationOptions) (map[string]rbacv1.PolicyRule, error)
- func NormalizePolicyRules(rules []rbacv1.PolicyRule, opts *PolicyRuleNormalizationOptions) ([]rbacv1.PolicyRule, error)
- func PolicyRulesMapToSlice(rulesMap map[string]rbacv1.PolicyRule) []rbacv1.PolicyRule
- func ResourcesToRole(resources Resources) (*rbacapi.Role, error)
- func RoleToResources(kargoRole *rbacapi.Role) (*corev1.ServiceAccount, *rbacv1.Role, *rbacv1.RoleBinding, error)
- func RuleKey(group, resource, resourceName string) string
- func VerifyResourceNotEscalating(ctx context.Context, authz kubernetes.Authorizer, resolver client.Client, ...) error
- type PolicyRuleNormalizationOptions
- type Resources
- type RolesDatabase
- type RolesDatabaseConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildNormalizedPolicyRulesMap ¶
func BuildNormalizedPolicyRulesMap( rules []rbacv1.PolicyRule, opts *PolicyRuleNormalizationOptions, ) (map[string]rbacv1.PolicyRule, error)
BuildNormalizedPolicyRulesMap returns a map of Normalized PolicyRules built from the the provided slice of PolicyRules. The map is keyed by the combination of group, resource, and if applicable, resourceName, as derived by the RuleKey() function. If the provided PolicyRules include wildcards in their APIGroups or Resources, this function will produce an error. Provided PolicyRules will be split or combined as necessary such that each rule references a single APIGroup, a single Resource, and at most a single ResourceName, with wildcard verbs expanded and all applicable verbs de-duplicated and sorted.
func NormalizePolicyRules ¶
func NormalizePolicyRules( rules []rbacv1.PolicyRule, opts *PolicyRuleNormalizationOptions, ) ([]rbacv1.PolicyRule, error)
NormalizePolicyRules returns a predictably ordered slice of Normalized PolicyRules built from the the provided slice of PolicyRules. If the provided PolicyRules include wildcards in their APIGroups or Resources, this function will produce an error. Provided PolicyRules will be split or combined as necessary such that each rule references a single APIGroup, a single Resource, and at most a single ResourceName, with wildcard verbs expanded and all applicable verbs de-duplicated and sorted.
func PolicyRulesMapToSlice ¶
func PolicyRulesMapToSlice(rulesMap map[string]rbacv1.PolicyRule) []rbacv1.PolicyRule
PolicyRulesMapToSlice returns a slice of PolicyRules built from the provided map.
func ResourcesToRole ¶
ResourcesToRole converts the provided ServiceAccount, Role, and RoleBinding into a Kargo Role with normalized policy rules. If the ServiceAccount is nil, the Kargo Role will be nil.
func RoleToResources ¶
func RoleToResources( kargoRole *rbacapi.Role, ) (*corev1.ServiceAccount, *rbacv1.Role, *rbacv1.RoleBinding, error)
RoleToResources converts the provided Kargo Role into a ServiceAccount/Role/RoleBinding trio.
func RuleKey ¶
RuleKey returns a single string that combines the provided group, resource, and if non-empty, resourceName. This key is suitable for use as a key in a map of RBAC PolicyRules.
func VerifyResourceNotEscalating ¶ added in v1.9.10
func VerifyResourceNotEscalating( ctx context.Context, authz kubernetes.Authorizer, resolver client.Client, globalNamespaces []string, obj *unstructured.Unstructured, ) error
VerifyResourceNotEscalating guards the generic resource endpoints against RBAC privilege escalation. The authorizing client checks only that the requester may perform the verb -- e.g. create Roles in the namespace -- not that they already hold the permissions the resource would grant; a SubjectAccessReview answers the former, never the latter. Kubernetes itself enforces the latter at admission, but against the identity performing the write -- and these endpoints write with the API server's own privileged credentials, so that check passes vacuously. This supplies what neither does: it requires the requester (bound to ctx) to already hold every permission the created or updated obj would confer.
Only these kinds confer permissions; any other returns nil:
- Role, ClusterRole: the rules they declare.
- RoleBinding, ClusterRoleBinding: the rules of the Role or ClusterRole they reference.
- ServiceAccount annotated for OIDC claim mapping: the rules of every Role and ClusterRole bound to it, because mapping a claim onto it hands those permissions to every user bearing that claim.
Each permission is verified at the scope where it applies: namespaced kinds in obj's namespace, cluster-scoped kinds cluster-wide. (A RoleBinding is namespaced even when it references a ClusterRole.)
authz runs the "does the requester already hold this?" checks; a nil authz disables verification (tests, non-authorizing local mode). resolver reads the Roles and bindings needed to decide and must always be able to read them, e.g. the server's internal client rather than one scoped to the requester. globalNamespaces matters only for the ServiceAccount case; see verifyServiceAccountBindingsNotEscalating.
Types ¶
type PolicyRuleNormalizationOptions ¶
type PolicyRuleNormalizationOptions struct {
// IncludeCustomVerbsInExpansion indicates whether custom verbs (like
// "promote" for Stages) should be included in the expansion of the "*"
// wildcard verb. This is optional because when normalizing PolicyRules with
// the intent to create or update a Role, this is how we would like "*" to be
// interpreted. However, when normalizing PolicyRules with the intent to
// display them to the user, we will not want to expand "*" to include custom
// verbs because Kubernetes own interpretation of "*" does not include custom
// verbs.
IncludeCustomVerbsInExpansion bool
}
type Resources ¶ added in v1.10.0
type Resources struct {
ServiceAccount *corev1.ServiceAccount
Roles []rbacv1.Role
ClusterRoles []rbacv1.ClusterRole
RoleBindings []rbacv1.RoleBinding
}
Resources is a struct that encapsulates the Kubernetes resources underlying a Kargo Role.
type RolesDatabase ¶
type RolesDatabase interface {
// Create creates the ServiceAccount, Role, and RoleBinding underlying a new
// Kargo Role. It will return an error if any of those resources already
// exist.
Create(context.Context, *rbacapi.Role) (*rbacapi.Role, error)
// Delete deletes a Kargo Role's underlying ServiceAccount, Role, and
// RoleBinding. It will return an error if no underlying resources exist or if
// any underlying resources are not Kargo-manageable.
Delete(ctx context.Context, project, name string) error
// Get returns a Kargo Role representation of an underlying ServiceAccount
// and any Roles it is associated with. It will return an error if no
// underlying ServiceAccount exists.
Get(
ctx context.Context,
systemLevel bool,
project string,
name string,
) (*rbacapi.Role, error)
// GetAsResources returns the ServiceAccount and any Roles and RoleBindings
// underlying a Kargo Role. It will return an error if no underlying
// ServiceAccount exists. It is valid for the Roles and/or RoleBindings to be
// missing, in which case they will be returned as nil.
GetAsResources(
ctx context.Context,
systemLevel bool,
project string,
name string,
) (Resources, error)
// GrantPermissionsToRole amends the Role underlying a Kargo Role with new
// rules. It will return an error if no underlying ServiceAccount exists or
// any underlying resources are not Kargo-manageable. It will create
// underlying Role and RoleBinding resources if they do not exist.
GrantPermissionsToRole(
ctx context.Context,
project string,
name string,
resourceDetails *rbacapi.ResourceDetails,
) (*rbacapi.Role, error)
// GrantRoleToUsers amends claim annotations of the ServiceAccount underlying
// a Kargo Role. It will return an error if no underlying ServiceAccount
// exists or any underlying resources are not Kargo-manageable.
GrantRoleToUsers(
ctx context.Context,
project string,
name string,
claims []rbacapi.Claim,
) (*rbacapi.Role, error)
// List returns Kargo Role representations of underlying ServiceAccounts and
// andy Roles and RoleBindings associated with them.
List(
ctx context.Context,
systemLevel bool,
project string,
) ([]*rbacapi.Role, error)
// ListNames returns names of Kargo Roles..
ListNames(
ctx context.Context,
systemLevel bool,
project string,
) ([]string, error)
// RevokePermissionFromRole removes select rules from the Role underlying a
// Kargo Role. It will return an error if no underlying ServiceAccount exists
// or any underlying resources are not Kargo-manageable.
RevokePermissionsFromRole(
ctx context.Context,
project string,
name string,
resourceDetails *rbacapi.ResourceDetails,
) (*rbacapi.Role, error)
// RevokeRoleFromUsers removes select claims from claim annotations of the
// ServiceAccount underlying a Kargo Role. It will return an error if no
// underlying ServiceAccount exists or any underlying resources are not
// Kargo-manageable.
RevokeRoleFromUsers(
ctx context.Context,
project string,
name string,
claims []rbacapi.Claim,
) (*rbacapi.Role, error)
// Update updates the underlying ServiceAccount and Role resources underlying
// a Kargo Role. It will return an error if no underlying ServiceAccount
// exists or any underlying resources are not Kargo-manageable. It will create
// underlying Role and RoleBinding resources if they do not exist.
Update(context.Context, *rbacapi.Role) (*rbacapi.Role, error)
// CreateAPIToken generates and returns a new bearer token associated with a
// Kargo Role in the form of a Kubernetes Secret.
CreateAPIToken(
ctx context.Context,
systemLevel bool,
project string,
roleName string,
tokenName string,
) (*corev1.Secret, error)
// DeleteAPIToken deletes a bearer token associated with a Kargo Role.
DeleteAPIToken(
ctx context.Context,
systemLevel bool,
project string,
name string,
) error
// GetAPIToken returns a bearer token associated with a Kargo Role.
GetAPIToken(
ctx context.Context,
systemLevel bool,
project string,
name string,
) (*corev1.Secret, error)
// ListAPITokens lists all bearer tokens associated with a specified Kargo
// Role.
ListAPITokens(
ctx context.Context,
systemLevel bool,
project string,
roleName string,
) ([]corev1.Secret, error)
}
RolesDatabase is an interface for the Kargo Roles store.
func NewKubernetesRolesDatabase ¶
func NewKubernetesRolesDatabase( c client.Client, internalClient client.Client, cfg RolesDatabaseConfig, ) RolesDatabase
NewKubernetesRolesDatabase returns an implementation of the RolesDatabase interface that utilizes a Kubernetes controller runtime client to store and retrieve Kargo Roles stored Kubernetes in the form of ServiceAccount/Role/RoleBinding trios.
type RolesDatabaseConfig ¶ added in v1.8.8
type RolesDatabaseConfig struct {
KargoNamespace string `envconfig:"KARGO_NAMESPACE" default:"kargo"`
}
func RolesDatabaseConfigFromEnv ¶ added in v1.8.8
func RolesDatabaseConfigFromEnv() RolesDatabaseConfig