The main changes here are:
- Using an LRU cache to store compiled regular expressions.
- Removing stack traces captured by trace.NotFound/trace.Wrap
when there are no matches.
This was heavily inspired by
https://github.com/gravitational/teleport/pull/23534 which made
similar changes to improve the performance of utils.MatchString.
The main beneficiaries of this change are services.MapRoles and
services.TraitsToRoles which rely heavily on
utils.ReplaceRegexp, utils.RegexpWithConfig, or ReplaceRegexpWith.
BenchmarkReplaceRegexp was added to validate the improvements in
this change and prevent regressions in the future. Results from
before and after this change:
benchstat old.txt new.txt
goos: darwin
goarch: arm64
pkg: github.com/gravitational/teleport/lib/utils
cpu: Apple M2 Pro
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
ReplaceRegexp/same_expression-12 29.527µ ± 12% 6.837µ ± 1% -76.84% (p=0.000 n=10)
ReplaceRegexp/unique_expressions-12 22.94µ ± 1% 25.10µ ± 1% +9.41% (p=0.002 n=10)
ReplaceRegexp/no_matches-12 24.692µ ± 3% 2.861µ ± 1% -88.41% (p=0.000 n=10)
geomean 25.57µ 7.889µ -69.15%
│ old.txt │ new.txt │
│ B/op │ B/op vs base │
ReplaceRegexp/same_expression-12 22071.5 ± 1% 164.0 ± 0% -99.26% (p=0.000 n=10)
ReplaceRegexp/unique_expressions-12 12.90Ki ± 1% 12.87Ki ± 0% ~ (p=0.165 n=10)
ReplaceRegexp/no_matches-12 14257.00 ± 1% 15.00 ± 0% -99.89% (p=0.000 n=10)
geomean 15.70Ki 318.8 -98.02%
│ old.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
ReplaceRegexp/same_expression-12 58.000 ± 0% 6.000 ± 0% -89.66% (p=0.000 n=10)
ReplaceRegexp/unique_expressions-12 55.00 ± 0% 55.00 ± 0% ~ (p=1.000 n=10) ¹
ReplaceRegexp/no_matches-12 58.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10)
geomean 56.98 ? ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean
* [kube] fix greedy deny rule blocking namespace list when blocking other resources
This PR fixes an edge case where the deny rule for blocking access to a resource becomes greedy and blocks access to the whole namespace.
eg:
```
allow:
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
name: '*'
namespace: '*'
verbs:
- '*'
deny:
kubernetes_resources:
- kind: secret
name: '*'
namespace: '*'
verbs:
- '*'
```
With the example above, access to secrets must be blocked but the user is allowed to access every other resource in any namespace.
The previous model was greedy and blocked access to namespace list.
* add extra test
* handle comments
* kube: Return errors when users aren't allowed to list resources
Previously to this commit, if the user was denied to list resources from
a certain namespace, Teleport would return an empty list instead of
returning an error if it's impossible for the request to match any
resource in that namespace.
This commit returns an error for cases where the role's
`kubernetes_resources` denies any resource to be returned. This is a
small nit to incorporate some customer expectations.
Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
* Update lib/utils/replace.go
Co-authored-by: Hugo Shaka <hugo.hervieux@goteleport.com>
* handle code review suggestions
* Update lib/utils/replace.go
Co-authored-by: Anton Miniailo <anton@goteleport.com>
* fix test names
---------
Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
Co-authored-by: Hugo Shaka <hugo.hervieux@goteleport.com>
Co-authored-by: Anton Miniailo <anton@goteleport.com>
This PR adds a RBAC controll logic for Kubernetes Custom Resources.
Access to clustom resources is determined by the access level of the
namespace resource where the custom resource is defined.
This is a special case because custom resources are not defined in the
user's resources list.
Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
This PR corrects the behavior of handling namespaces for Kubernetes
per-Resource RBAC.
The new behavior allows accessing the resources withing the namespace
`someNamespace` if a rule `kind: namespace, name: someNamespace` is
defined for `kubernetes_resources`.
It also allows users to see namespaces (list, get or watch requests) if
they have other resources defined for the namepsace without requiring
explicit rules for `kind:namespace, name: someNamespace`.
As an example:
```yaml
allow:
kubernetes_resources:
- kind: namespace
name: someNamespace
- kind: pod
namespace: otherNamespace
name: *
```
Reads as: the user has access to everything in namespace someNamespace
AND to pods in otherNamespace.
```
$ kubectl get ns
someNamespace
otherNamespace
```
Pods:
```
$ kubectl get pods -n someNamespace
pod1
pod2
$ kubectl get pods -n otherNamespace
pod3
pod4
```
Other resources:
```
$ kubectl get secret -n someNamespace
secret1
secret2
$ kubectl get secret -n otherNamespace
REQUEST IS DENIED
```
* Extend Teleport RBAC to suport Kubernetes Verbs
This PR extends Teleport per-Resource RBAC to support Kubernetes verbs
restriction. With this change it's possible to restrict certain actions
allowed by the underlying `kubernetes_users` and `kubernetes_resources`.
Supported verbs:
- `get`
- `create`
- `update`
- `patch`
- `delete`
- `list`
- `watch`
- `deletecollection`
Fixes#27095
* address timr's comments
* assign wildcard to verbs for role <7
* address marco's reviews
This PR introduces a mechanism to control access to Pods in Kubernetes clusters based on access criteria defined in user Roles or Resource Access Requests.
New `Role` version - `v6` - introduced a new field `kubernetes_resources` that allows admins to restrict access to a subset of cluster resources based on the configuration provided.
This PR implements the resource control for `pods` and allows
```yaml
kubernetes_resources:
- kind: pod
name: nginx-*
namespace: default
- kind: pod
name: *
namespace: dev
```
It also implements the logic blocks for supporting Resource Access Requests to Kubernetes Pods. The tsh boilerplate is not included in this PR and will be included in future PRs.
An example of usage:
```
tsh request search --kind pod --kube-cluster=minikube
Name Namespace Labels Resource ID
--------------------------------- --------- -------------------------------------- ---------------------------------------------
nginx-deployment-6595874d85-6j2zm default app=nginx,pod-template-hash=6595874d85 /tele.teleport.local/pod/minikube/default/...
nginx-deployment-6595874d85-7xgmb default app=nginx,pod-template-hash=6595874d85 /tele.teleport.local/pod/minikube/default/...
nginx-deployment-6595874d85-c4kz8 default app=nginx,pod-template-hash=6595874d85 /tele.teleport.local/pod/minikube/default/...
test default run=test /tele.teleport.local/pod/minikube/default/...
To request access to these resources, run
> tsh request create --resource /tele.teleport.local/pod/minikube/default/nginx-deployment-6595874d85-6j2zm --resource /tele.teleport.local/pod/minikube/default/nginx-deployment-6595874d85-7xgmb --resource /tele.teleport.local/pod/minikube/default/nginx-deployment-6595874d85-c4kz8 --resource /tele.teleport.local/pod/minikube/default/test \
--reason <request reason>
```
Part of #18434