Skip to content
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

[v16] Add workload_identity_labels to RoleCondition (#50071) #50136

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3288,6 +3288,18 @@ message RoleConditions {
reserved "SAMLIdPServiceProviderLabels";
reserved 41; // removed saml_idp_service_provider_labels_expression in favor of using app_labels_expression.
reserved "SAMLIdPServiceProviderLabelsExpression";

// WorkloadIdentityLabels controls whether or not specific WorkloadIdentity
// resources can be invoked. Further authorization controls exist on the
// WorkloadIdentity resource itself.
wrappers.LabelValues WorkloadIdentityLabels = 44 [
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "workload_identity_labels,omitempty",
(gogoproto.customtype) = "Labels"
];
// WorkloadIdentityLabelsExpression is a predicate expression used to
// allow/deny access to issuing a WorkloadIdentity.
string WorkloadIdentityLabelsExpression = 45 [(gogoproto.jsontag) = "workload_identity_labels_expression,omitempty"];
}

// SPIFFERoleCondition sets out which SPIFFE identities this role is allowed or
Expand Down
81 changes: 81 additions & 0 deletions api/types/resource_153.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"

headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/api/utils"
)

// ResourceMetadata is the smallest interface that defines a Teleport resource.
Expand Down Expand Up @@ -212,3 +213,83 @@ func (r *resource153ToLegacyAdapter) SetRevision(rev string) {
func (r *resource153ToLegacyAdapter) SetSubKind(subKind string) {
panic("interface Resource153 does not implement SetSubKind")
}

// Resource153ToResourceWithLabels wraps a [Resource153]-style resource in
// the legacy [Resource] and [ResourceWithLabels] interfaces.
//
// The same caveats that apply to [Resource153ToLegacy] apply.
func Resource153ToResourceWithLabels(r Resource153) ResourceWithLabels {
return &resource153ToResourceWithLabelsAdapter{
resource153ToLegacyAdapter{
inner: r,
},
}
}

// resource153ToResourceWithLabelsAdapter wraps a new-style resource in a
// type implementing the legacy resource interfaces
type resource153ToResourceWithLabelsAdapter struct {
resource153ToLegacyAdapter
}

// Origin implements ResourceWithLabels for the adapter.
func (r *resource153ToResourceWithLabelsAdapter) Origin() string {
m := r.inner.GetMetadata()
if m == nil {
return ""
}
return m.Labels[OriginLabel]
}

// SetOrigin implements ResourceWithLabels for the adapter.
func (r *resource153ToResourceWithLabelsAdapter) SetOrigin(origin string) {
m := r.inner.GetMetadata()
if m == nil {
return
}
m.Labels[OriginLabel] = origin
}

// GetLabel implements ResourceWithLabels for the adapter.
func (r *resource153ToResourceWithLabelsAdapter) GetLabel(key string) (value string, ok bool) {
m := r.inner.GetMetadata()
if m == nil {
return "", false
}
value, ok = m.Labels[key]
return
}

// GetAllLabels implements ResourceWithLabels for the adapter.
func (r *resource153ToResourceWithLabelsAdapter) GetAllLabels() map[string]string {
m := r.inner.GetMetadata()
if m == nil {
return nil
}
return m.Labels
}

// GetStaticLabels implements ResourceWithLabels for the adapter.
func (r *resource153ToResourceWithLabelsAdapter) GetStaticLabels() map[string]string {
return r.GetAllLabels()
}

// SetStaticLabels implements ResourceWithLabels for the adapter.
func (r *resource153ToResourceWithLabelsAdapter) SetStaticLabels(labels map[string]string) {
m := r.inner.GetMetadata()
if m == nil {
return
}
m.Labels = labels
}

// MatchSearch implements ResourceWithLabels for the adapter. If the underlying
// type exposes a MatchSearch method, this method will defer to that, otherwise
// it will match against the resource label values and name.
func (r *resource153ToResourceWithLabelsAdapter) MatchSearch(searchValues []string) bool {
if matcher, ok := r.inner.(interface{ MatchSearch([]string) bool }); ok {
return matcher.MatchSearch(searchValues)
}
fieldVals := append(utils.MapToStrings(r.GetAllLabels()), r.GetName())
return MatchSearch(fieldVals, searchValues, nil)
}
33 changes: 33 additions & 0 deletions api/types/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ type Role interface {
// SetNodeLabels sets the map of node labels this role is allowed or denied access to.
SetNodeLabels(RoleConditionType, Labels)

// GetWorkloadIdentityLabels gets the map of node labels this role is
// allowed or denied access to.
GetWorkloadIdentityLabels(RoleConditionType) Labels
// SetWorkloadIdentityLabels sets the map of WorkloadIdentity labels this
// role is allowed or denied access to.
SetWorkloadIdentityLabels(RoleConditionType, Labels)

// GetAppLabels gets the map of app labels this role is allowed or denied access to.
GetAppLabels(RoleConditionType) Labels
// SetAppLabels sets the map of app labels this role is allowed or denied access to.
Expand Down Expand Up @@ -604,6 +611,25 @@ func (r *RoleV6) SetNodeLabels(rct RoleConditionType, labels Labels) {
}
}

// GetWorkloadIdentityLabels gets the map of WorkloadIdentity labels for
// allow or deny.
func (r *RoleV6) GetWorkloadIdentityLabels(rct RoleConditionType) Labels {
if rct == Allow {
return r.Spec.Allow.WorkloadIdentityLabels
}
return r.Spec.Deny.WorkloadIdentityLabels
}

// SetWorkloadIdentityLabels sets the map of WorkloadIdentity labels this role
// is allowed or denied access to.
func (r *RoleV6) SetWorkloadIdentityLabels(rct RoleConditionType, labels Labels) {
if rct == Allow {
r.Spec.Allow.WorkloadIdentityLabels = labels.Clone()
} else {
r.Spec.Deny.WorkloadIdentityLabels = labels.Clone()
}
}

// GetAppLabels gets the map of app labels this role is allowed or denied access to.
func (r *RoleV6) GetAppLabels(rct RoleConditionType) Labels {
if rct == Allow {
Expand Down Expand Up @@ -1225,6 +1251,7 @@ func (r *RoleV6) CheckAndSetDefaults() error {
r.Spec.Allow.DatabaseLabels,
r.Spec.Allow.WindowsDesktopLabels,
r.Spec.Allow.GroupLabels,
r.Spec.Allow.WorkloadIdentityLabels,
} {
if err := checkWildcardSelector(labels); err != nil {
return trace.Wrap(err)
Expand Down Expand Up @@ -1906,6 +1933,8 @@ func (r *RoleV6) GetLabelMatchers(rct RoleConditionType, kind string) (LabelMatc
return LabelMatchers{cond.WindowsDesktopLabels, cond.WindowsDesktopLabelsExpression}, nil
case KindUserGroup:
return LabelMatchers{cond.GroupLabels, cond.GroupLabelsExpression}, nil
case KindWorkloadIdentity:
return LabelMatchers{cond.WorkloadIdentityLabels, cond.WorkloadIdentityLabelsExpression}, nil
}
return LabelMatchers{}, trace.BadParameter("can't get label matchers for resource kind %q", kind)
}
Expand Down Expand Up @@ -1956,6 +1985,10 @@ func (r *RoleV6) SetLabelMatchers(rct RoleConditionType, kind string, labelMatch
cond.GroupLabels = labelMatchers.Labels
cond.GroupLabelsExpression = labelMatchers.Expression
return nil
case KindWorkloadIdentity:
cond.WorkloadIdentityLabels = labelMatchers.Labels
cond.WorkloadIdentityLabelsExpression = labelMatchers.Expression
return nil
}
return trace.BadParameter("can't set label matchers for resource kind %q", kind)
}
Expand Down
Loading
Loading