* Remove JSON schema validation
Removing JSON schema validation from all resource unmarshalers.
--- what JSON schema gets us
Looking at the JSON schema spec and our usage, here are the supposed benefits:
- type validation - make sure incoming data uses the right types for the right fields
- required fields - make sure that mandatory fields are set
- defaulting - set defaults for fields
- documentation - schema definition for our API objects
Note that it does _not_ do:
- fail on unknown fields in data
- fail on a required field with an empty value
--- what replaces it
Based on the above, it may seem like JSON schema provides value.
But it's not the case, let's break it down one by one:
- type validation - unmarshaling JSON into a typed Go struct does this
- required fields - only checks that the field was provided, doesn't actually check that a value is set (e.g. `"name": ""` will pass the `required` check)
- so it's pretty useless for any real validation
- and we already have a separate place for proper validation - `CheckAndSetDefaults` methods
- defaulting - done in `CheckAndSetDefaults` methods
- `Version` is the only annoying field, had to add it in a bunch of objects
- documentation - protobuf definitions are the source of truth for our API schema
--- the benefits
- performance - schema validation does a few rounds of `json.Marshal/Unmarshal` in addition to actual validation; now we simply skip all that
- maintenance - no need to keep protobuf and JSON schema definitions in sync anymore
- creating new API objects - one error-prone step removed
- (future) fewer dependencies - we can _almost_ remove the Go libraries for schema validation (one transient dependency keeping them around)
* Remove services.SkipValidation
No more JSON schema validation so this option is a noop.
Fixes#5352
```yaml
allow:
impersonate:
users: ['alice', 'bob']
roles: ['*']
where: 'contains(user.spec.traits["groups"], impersonate_role.traits)'
```
Adds "impersonator" to all X.509 and SSH client certs
issued using impersonation and does best effort to track
requests by impersonators in audit events.
Limits certs TTL to the impersonator's max session TTL.
Prevents impersonating users to recursively impersonate
other users.
Allows impersonating users to renew their own certificate,
for example to set route to cluster.
Adds missing token permission for editor role.
Fixes#3604
This commit adds support for cluster_labels
role parameter limiting access to remote clusters by label.
New tctl update rc provides interface to set labels on remote clusters.
Consider two clusers, `one` - root and `remote` - leaf.
```bash
$ tsh clusters
Cluster Name Status
------------ ------
one online
two online
```
Create the trusted cluster join token with labels:
```bash
$ tctl tokens add --type=trusted_cluster --labels=env=prod
```
Every cluster joined using this token will inherit env:prod labels.
Alternatively, update remote cluster labels by modifying
`rc` command. Letting remote clusters to propagate their labels
creates a problem of rogue clusters updating their labels to bad values.
Instead, administrator of root cluster control the labels
using remote clusters API without fear of override:
```bash
$ tctl get rc
kind: remote_cluster
metadata:
name: two
status:
connection: online
last_heartbeat: "2020-09-14T03:13:59.35518164Z"
version: v3
```
```bash
$ tctl update rc/two --set-labels=env=prod
cluster two has been updated
```
```bash
$ tctl get rc
kind: remote_cluster
metadata:
labels:
env: prod
name: two
status:
connection: online
last_heartbeat: "2020-09-14T03:13:59.35518164Z"
```
Update the role to deny access to prod env:
```yaml
kind: role
metadata:
name: dev
spec:
allow:
logins: [root]
node_labels:
'*': '*'
# Cluster labels control what clusters user can connect to. The wildcard ('*') means
# any cluster. If no role in the role set is using labels and cluster is not labeled,
# the cluster labels check is not applied. Otherwise, cluster labels are always enforced.
# This makes the feature backwards-compatible.
cluster_labels:
'env': 'staging'
deny:
# cluster labels control what clusters user can connect to. The wildcard ('*') means
# any cluster. By default none is set in deny rules to preserve backwards compatibility
cluster_labels:
'env': 'prod'
```
```bash
$ tctl create -f dev.yaml
```
Cluster two is now invisible to user with `dev` role.
```bash
$ tsh clusters
Cluster Name Status
------------ ------
one online
```
This commit introduces GRPC API for streaming sessions.
It adds structured events and sync streaming
that avoids storing events on disk.
You can find design in rfd/0002-streaming.md RFD.
Prior to this commit, RemoteCluster resource data was dynamically
generated from TunnelConnection resources.
Keep using TunnelConnections, but record any changes to RemoteCluster in
the backend too. This lets us preserve the LastHeartbeat field after
TunnelConnections get deleted (as they do when a reverse tunnel
disconnects).
Our auth middleware already attaches a TLS identity as context value.
Plumb contexts through and extract the username when recording events.
If the received context doesn't have an identity attached, use "system"
as username.
Lots of noise here due to missing context.Context plumbing :(
We should eventually plumb contexts to all those RPC interfaces.
Updates #3816
This commit improves performance of teleport with
hundreds of connected trusted clusters.
TLS handshake protocol expects server to send a
list of trusted certificate authorities to the client
and client must present certificate signed by those.
With Teleport current implementation, every remote cluster
client is signed by local certificate and is not cross
signed.
Auth server now expects clients to announce the
remote cluster they are connecting from using SNI.
Auth server will send only certificate authorities
of the cluster announced via SNI.
Alternative idea is to cross sign the certificate
of the client of the remote cluster. We will explore
this idea in the next releases.
This commit also removes unnecessary reads
from the database to check the remote server status
that slows down user interface and other clients.
This is done at the expense of proxies showing
servers as offline in case if this individual
proxy does not have the connection, although
it's a small UI price to pay for not reading
the database, as proxy will eventually
get the connection thanks to the discovery
protocol.
This commit adds two extensions to template variables
in roles and adds support for regular expressions
and group captures in role mapping of trusted clusters.
1. Roles node_labels can expand variables from traits:
allow:
node_labels:
'{{external.key}}': '{{external.val}}'
deny:
node_labels:
'{{external.key}}': '{{external.val}}'
If traits variable is not found, label key pair in allow or
deny rule will be set to empty key or value, so if 'external.val'
trait is missing, the resulting role will not match
allow or deny rule:
allow:
node_labels:
'': 'val'
deny:
node_labels:
'': 'val'
Same thing will happen for missing value:
allow:
node_labels:
'key': ''
deny:
node_labels:
'key': ''
2. Trusted cluster role mapping can now
support advanced expressions:
a. Glob values will math any string, including
empty one
role_map:
- remote: 'cluster-*'
local: [clusteradmin]
a. Regular expression syntax is supported:
Syntax: https://github.com/google/re2/wiki/Syntax
Brackets can be used as a capture group and referred
to with expand variable:
role_map:
- remote: '^clusteradmin-(.*)$'
local: [unprivileged-$1]
Will map incoming role 'clusteradmin-account-1' to 'guest-account-1'.
3. Same regular expression syntax is supported for SAML and OIDC
mappings:
a. Glob matches of values instead of static matches:
claims_to_roles:
- {claim: "roles", value: "gravitational/*", roles: ["clusteradmin"]}
b. Regexp matches with subgroup expands:
attributes_to_roles:
- {name: "roles", value: "^gravitational/(.*)$", roles: ["cluster-$1"]}
This commit makes sure that trusted cluster resource
name is the same name as the cluster name it conects to.
If user supplies name of the trusted cluster resource
that is different from the cluster name, the warning
will be issued and trusted cluster will be renamed.
Upgrade procedure renames existing trusted clusters
in place.
If user supplies trusted cluster without role
mappings, or with role mappings referring to
non-existent roles that do not exist, the
error will be returned.
This commit adds remote cluster resource that specifies
connection and trust of the remote trusted cluster to the local
cluster. Deleting remote cluster resource deletes trust
established between clusters on the local cluster side
and terminates all reverse tunnel connections.
Migrations make sure that remote cluster resources exist
after upgrade of the auth server.
This commit introduced mutual TLS authentication
for auth server API server.
Auth server multiplexes HTTP over SSH - existing
protocol and HTTP over TLS - new protocol
on the same listening socket.
Nodes and users authenticate with 2.5.0 Teleport
using TLS mutual TLS except backwards-compatibility
cases.
Instead of quietly changing behavior because `DEBUG` envar was set to
true, Teleport now explicitly requires scary --insecure flag to enable
this behavior.