Adds `UpsertCertAuthority` to the `teleport.v1.trust.TrustService`
and deprecates the HTTP api. The `services.Trust` interface was
also updated to include a `context.Context` in both
`CreateCertAuthority` and `UpsertCertAuthority.
To ensure backwards compatibility the `auth.Client` will first
attempt to use the gRPC client and if that fails with a not
implemented error it will fallback to using HTTP.
Part of #6394
* Move the authorizer into its own package.
The Authorizer and associated functions and constants have been moved into
their own package `authz`. This will allow us to more easily create separate
services for gRPC functionality so that we're not pushing as much into the
`lib/auth` package.
Though this PR is large, the only actual code change here is making
`ContextForLocalUser` exported and changing the `permissions_test.go` so that
it doesn't rely on the `lib/auth` package.
* Use context functions.
* Test and linting fixes.
* Add in a temporary alias file to ensure e still compiles.
* Use functions instead of var aliases for performance reasons.
* Adding in godocs, cleaning up tests.
* Fix tests.
* Add a few more aliases.
* Start removing generateToken
* Refactor `tokens add` to use `CreateToken` RPC
* Correct deprecation version
* Remove calls to GenerateToken
* Start tests for token crud
* Allow user role rules to be provided wth CreateUserAndRole helper
* Add TestCreateToken to tls_test
* Add TestUpsertToken
* Add GetTokens test
* Add TestGetToken
* Add test for DeleteToken RPC
* Dedupe error assertions
* Add support for emitting trusted cluster token creation events to Create/UpsertToken
* Fix imports
* Change parameter order to appease linter
* Fix broken token expiry test
* Fix token expiry time for TestAuth_RegisterUsingToken
* Remove unnecessary cleanup
* Apply suggestions from code review
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Change test comment from deprecation notice
* `make gprc` after code review changes
* Update lib/auth/tls_test.go
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Update lib/auth/tls_test.go
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Update lib/auth/tls_test.go
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Update lib/auth/tls_test.go
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Rename tests
* Update lib/auth/tls_test.go
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* More test cases for GetTokens
* Improve message on duplicate token
---------
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Test device authorization during cert issuance
* Skip device validation when issuing App or Windows certs
* Add an early check for GenerateUserSingleUseCerts
* WIP adding OpenSSH CA
* fix creating OpenSSH CA for tests
* fix a test name and tctl usage flag
* fix 'tctl status' not displaying openssh CA sometimes
* add OpenSSH CA to TestInit_bootstrap, remove TLS key pair
* add OpenSSH CA to a few more places
* make help text of 'tctl auth rotate' more helpful and accurate
* fix web cert export test
* tbot doesn't need to know about OpenSSH CA
* address feedback
* fix comment formatting
This PR includes a new Role resource version that is compatible with V5 spec.
The new resource introduces the `kubernetes_resources` definition that allows operators to limit the Kubernetes resources that each member can access. The `kubernetes_resources` entries must follow the following format: `{"kind":"<kind>", "namespace":"<namespace>","name":"<pod>"}`. Currently, it only supports objects of `kind` `pod`. Valid examples `<namespace>/<name>:
- `*/*`: matches all pods in all namespaces.
- `default/*`: matches all pods in the `default` namespace.
- `*/nginx-*`: matches every pod prefixed with `nginx-` in every namespace.
For older resource versions - V5, V4, V3 - `kubernetes_resources` is automatically populated with `{"kind":"pod","namespace":"*","name":"*"}` to keep compatibility. For the newest version, it's mandatory to define its value otherwise access to pods will be denied.
Part of #18434
Enable device authorization by plugging into auth.Authorizer and selectively
disabling it for processes that don't (yet) want device authz.
`GenerateUserCerts` is modified to issue device-aware certificates (DB/k8s
access), as well as `CreateAppSession`. The latter is not necessary for DB
access, but it does enable App Access to issue device-aware certs - commands
such as `tsh apps login` and `tsh proxy app` can benefit from those.
DB access is now ready to benefit from trusted devices. k8s access is likely
supported with these changes as well, but I've postponed enabling it after I've
done more testing.
Both `GenerateUserCerts` and `GenerateUserSingleUseCerts` now do early
device-aware authorization; this creates a better UX, as it allows us to return
error messages directly via `tsh`, instead of having to pipe them through
database-specific protocols. Further PRs could improve errors for scenarios
where the existing certificate became lacking due to higher server-side authz
enforcement.
gravitational/teleport.e#514
Add device-aware authorization for SSH access, including both long-lived and
single-use certificates.
If the device trust mode is set to "required", then the presence of the
corresponding extensions is enforced. (Requires Teleport Enterprise.)
Adds logic related to TLS validation and single-use certificates as well, where
appropriate. TLS device-aware validation is not wired into Teleport yet, but
will be in follow up PRs.
gravitational/teleport.e#514
Provide defaults for `TestTLSServerConfig` when passed to
`auth.NewTestServer()`, as some of those fields cannot be set from
outside `NewTestServer()`. The defaults are the same as when called
without a `TestTLSServerConfig`, which allows just some fields to be
set/overridden.
This is to allow `APIConfig.PluginRegistry` to be set.
* feat: set cluster connector name on first user signin
* perf: move is passwordless enabled before get users
* fix: move logic to correct handler
* test: test setting default passwordless connector name for cloud (positive case)
* test: add negative test cases
* refactor: flatten nested code
* fix: remove return in case auth preference was not set
* fix: run logic only in cloud
* docs: typo
* fix: run when passwordless
* test: move trySettingConnectorNameToPasswordless as separete method
* docs: add safety comments
* test: rephrase safety comment
* refactor: remove space between call and error check
* fix: remove unnessesery error log from trySettingConnectorNameToPasswordless
* refactor: pass context, rename session context
* docs: add description to trySettingConnectorNameToPasswordless
* test: add descriptive assertion text
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* refactor: simplify error handilng
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* fix: check for non default setting
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* test: correct RPID
* refactor: simplify user creation
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* docs: fix typo
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* test: reorder name filed in the test cases struct
* test: better names for test cases
* refactor: generate token instead of hardcoding arbitrary value
* test: remove user agent header
* fix: check for empty password
* docs: add passwordless check description
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* test: add "first cloud sign-in does not change custom connector"
* test: use correct number of users in "first cloud sign-in does not change custom connector"
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* test: remove is cloud check from test helpers, instead use config
* refactor: store is_passwordless_registration in variable
* test: first cloud sign-in with password does not change connector
* refactor: change isPasswordlessRegistration name
Co-authored-by: Alan Parra <alan.parra@goteleport.com>
* Tag forwarded spans with custom attributes
Adds a `teleport.forwarded.for` attribute to a resource or
all spans that are forwarded to the auth server. This allows
consumers of the spans to identify where the spans are coming
from and take possible action. In some scenarios it may
be desirable to drop forwarded spans along the collection
process, by tagging them we can provide a way for those
consumers to identify them. It also allows for potentially
identifying a malicious user that may be trying to spam the
telemetry backend with spans.
Part of #12241
* Embed auth.Cache in auth.Server
* Hit the backend during Auth initialization
* Bypass the cache when rotating CAs
* Services.UpsertTrustedCluster is different
* Bypass the cache in waitForTunnelConnections
* Fix infinite recursion
* More cache bypassing during init and rotations
* Rename Services to Uncached in auth.Server
* Further cleanups
* Don't start the auth cache immediately
* Go back to Services rather than Uncached
* Comments and a missing method
* Attempt to deflake TestAgentForward
This was another case of the t.TempDir() being cleaned up while the
audit logger is still writing to the directory, which happens when
tests don't properly clean up after themselves. Ensure that any
services we spin up closed via cleanup actions.
* Prevent the use of disk-based logging in TestAgentForward
The disk-based logger runs a background process to complete uploads,
which occaisionally fails to finish before the test cleanup tries
to remove the temporary directory.
There are two ways to prevent the use of a disk based logger:
1. Set IsTestStub on the SSH *ServerContext
2. Use a sync session recording mode
Option 2 was selected, because the ServerContext is created by the SSH
server instead of the test, so plumbing that value through would be
a larger change, and I generally dislike test specific modes that can
be mistakenly enabled in non-test situations.
Additionally, update the lib/srv/regular test fixture to allow for
configuring the audit log to use. This allows us to set up a dicarding
logger, since these tests are about agent forwarding behavior and not
audit logging.
* Remove more deprecated code
In the case where we were using the PostalCode, StreetAddress,
and Province fields rather than ASN.1 extensions we could have
removed more code, but I opted for a phase approach where we stop
populating the fields in v10 (but still accept them), and then
stop reading them entirely in v11.
* Fix lints and remove more unused code
* Restore StreetAddress / PostalCode
We don't yet have dedicated extensions for these
* Add client side circuit breaker to auth clients
In order to apply back pressure we can utilize a circuit breaker that
monitors error responses from auth server. When tripped it will prevent
all outbound requests to auth for a period of time. This can also help
prevent a potential thundering heard when auth is in an unhealthy state.
By default the circuit breaker will only be tripped if 90% of the
requests made in the monitoring interval fail.
* add client ip and user agent to `user.login` audit log
* reuse existing ConnectionMetadata message
* additional audit data for SSH logins made via proxy
* small unit test for clientMetaFromReq
* add franktentest for login checking audit event
* fix audit logging timestamps in web/auth tests
Introduce Database Certificate Authority. New CA is used by Database Access to sign database certificates making them independent from Host CA.
Co-authored-by: Marek Smoliński <marek@goteleport.com>
The Forwarder type has been replaced with the new GRPC/streaming based
session recording and was only used in tests.
The RecordSessions param is never consulted, as it was replaced with
AuditWriter's RecordOutput param a couple of years ago.
* Fix goroutine and memory leak in watchCertAuthorities
The CA Watcher was blocking both on writing to a channel when the watcher
was closed and on HTTP calls that had no request timeout or context passed
to cause cancellation.
All resourceWatcher implementations that had a bug which may cause them to block
on writing to a channel forever were fixed by selecting on the write and ctx.Done.
Adding context.Context to all Get/Put/Post/Delete methods on the auth HTTPClient to
force callers to propagate context. Prior all calls used context.TODO which
prevents requests from being properly cancelled.
Add context propagation to RotateCertAuthority, RotateExternalCertAuthority,
GetCertAuthority, GetCertAuthorities. This is needed to get the correct ctx
from the CertAtuhorityWatcher all the way down to the HTTPClient that makes
the call.
Closes#10648
* Add certificate renewal bot
This adds a new `tbot` tool to continuously renew a set of
certificates after registering with a Teleport cluster using a
similar process to standard node joining.
This makes some modifications to user certificate generation to allow
for certificates that can be renewed beyond their original TTL, and
exposes new gRPC endpoints:
* `CreateBotJoinToken` creates a join token for a bot user
* `GenerateInitialRenewableUserCerts` exchanges a token for a set of
certificates with a new `renewable` flag set
A new `tctl` command, `tctl bots add`, creates a bot user and calls
`CreateBotJoinToken` to issue a token. A bot instance can then be
started using a provided command.
* Cert bot refactoring pass
* Use role requests to split renewable certs from end-user certs
* Add bot configuration file
* Use `teleport.dev/bot` label
* Remove `impersonator` flag on initial bot certs
* Remove unnecessary `renew` package
* Misc other cleanup
* Do not pass through `renewable` flag when role requests are set
This adds additional restrictions on when a certificate's `renewable`
flag is carried over to a new certificate. In particular, it now also
denies the flag when either role requests are present, or the
`disallowReissue` flag has been previously set.
In practice `disallow-reissue` would have prevented any undesired
behavior but this improves consistency and resolves a TODO.
* Various tbot UX improvements; render SSH config
* Fully flesh out config template rendering
* Fix rendering for SSH configuration templates
* Added `String()` impls for destination types
* Improve certificate renewal logging; show more detail
* Properly fall back to default (all) roles
* Add mode hints for files
* Add/update copyright headers
* Add stubs for tbot init and watch commands
* Add gRPC endpoints for managing bots
* Add `CreateBot`, `DeleteBot`, and `GetBotUsers` gRPC endpoints
* Replace `tctl bot (add|rm|ls)` implementations with gRPC calls
* Define a few new constants, `DefaultBotJoinTTL`, `BotLabel`,
`BotGenerationLabel`
* Fix outdated destination flag in example tbot command
* Bugfix pass for demo
* Fixed a few nil pointer derefs when using config from CLI args
* Properly create destination if `--destination-dir` flag is used
* Remove improper default on CLI flag
* `DestinationConfig` is now a list of pointers
* Address first wave of review feedback
Fixes the majority of smaller issues caught by reviewers, thanks all!
* Add doc comments for bot.go functions
* Return the token TTL from CreateBot
* Split initial user cert issuance from `generateUserCerts()`
Issuing initial renewable certificate ended up requiring a lot of
hacks to skip checks that prevented anonymous bots from getting
certs even though we'd verified their identity elsewhere (via token).
This reverts all those hacks and splits initial bot cert logic into a
dedicated `generateInitialRenewableUserCerts()` function which should
make the whole process much easier to follow.
* Set bot traits to silence log messages
* tbot log message consistency pass
* Resolve lints
* Add config tests
* Remove CreateBotJoinToken endpoint
Users should instead use the CreateBot/DeleteBot endpoints.
* Create a fresh private key for every impersonated identity renewal
* Hide `config` subcommand
* Rename bot label prefix to `teleport.internal/`
* Use types.NewRole() to create bot roles
* Clean up error handling in custom YAML unmarshallers
Also, add notes about the supported YAML shapes.
* Fetch proxy host via gRPC Ping() instead of GetProxies()
* Update lib/auth/bot.go
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* Fix some review comments
* Add renewable certificate generation checks (#10098)
* Add renewable certificate generation checks
This adds a new validation check for renewable certificates that
maintains a renewal counter as both a certificate extension and a
user label. This counter is used to ensure only a single certificate
lineage can exist: for example, if a renewable certificate is stolen,
only one copy of the certificate can be renewed as the generation
counter will not match
When renewing a certificate, first the generation counter presented
by the user (via their TLS identity) is compared to a value stored
with the associated user (in a new `teleport.dev/bot-generation`
label field). If they aren't equal, the renewal attempt fails.
Otherwise, the generation counter is incremented by 1, stored to the
database using a `CompareAndSwap()` to ensure atomicity, and set on
the generated certificate for use in future renewals.
* Add unit tests for the generation counter
This adds new unit tests to exercise the generation counter checks.
Additionally, it fixes two other renewable cert tests that were
failing.
* Remove certRequestGeneration() function
* Emit audit event when cert generations don't match
* Fully implement `tctl bots lock`
* Show bot name in `tctl bots ls`
* Lock bots when a cert generation mismatch is found
* Make CompareFailed respones from validateGenerationLabel() more actionable
* Update lib/services/local/users.go
Co-authored-by: Nic Klaassen <nic@goteleport.com>
* Backend changes for tbot IoT and AWS joining (#10360)
* backend changes
* add token permission check
* pass ctx from caller
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
* fix comment typo
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
* use UserMetadata instead of Identity in RenewableCertificateGenerationMismatch event
* Client changes for tbot IoT joining (#10397)
* client changes
* delete replaced APIs
* delete unused tbot/auth.go
* add license header
* don't unecessarily fetch host CA
* log fixes
* s/tunnelling/tunneling/
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* auth server addresses may be proxies
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* comment typo fix
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* move *Server methods out of auth_with_roles.go (#10416)
Co-authored-by: Tim Buckley <tim@goteleport.com>
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
Co-authored-by: Tim Buckley <tim@goteleport.com>
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
Co-authored-by: Tim Buckley <tim@goteleport.com>
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
Co-authored-by: Nic Klaassen <nic@goteleport.com>
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* Address another batch of review feedback
* Addres another batch of review feedback
Add `Role.SetMetadata()`, simplify more `trace.WrapWithMessage()`
calls, clear some TODOs and lints, and address other misc feedback
items.
* Fix lint
* Add missing doc comments to SaveIdentity / LoadIdentity
* Remove pam tag from tbot build
* Update note about bot lock deletion
* Another pass of review feedback
Ensure all requestable roles exist when creating a bot, adjust the
default renewable cert TTL down to 1 hour, and check types during
`CompareAndSwapUser()`
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
Co-authored-by: Nic Klaassen <nic@goteleport.com>
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
Explicity set Kubernetes feature for the test.
The test requires the Kubernetes feature to be enabled while not
explicitly enabling it on its own. Sometimes it is enabled and other
times it is not, resulting in an error.
* Allow impersonation of roles without users
This adds the ability to impersonate one or more roles without
impersonating a particular user.
In Teleport today, when creating an impersonator role, both users and
roles must be specified as impersonation is fundamentally tied to an
existing Teleport user:
```yaml
allow:
impersonate:
users: ['jenkins']
roles: ['jenkins']
```
This is inconvenient for two reasons:
1. A user must exist for each set of roles you'd like to
impersonate, creating a UX burden.
2. It makes it difficult to use impersonation to reduce one's
permissions as you always inherit all of the roles granted to the
target user.
For the [certificate bot][bot] we'd instead like to use impersonation
to generate end-user (impersonated) certificates with a reduced set
of permissions. For example, given the following role:
```yaml
allow:
impersonate:
roles: ['jenkins', 'deploy']
```
We can then use `GenerateUserCerts` to issue certifices for a subset
of the allowed roles, e.g. one set of certificates with only the
`jenkins` role attached, and another with only `deploy`.
To that end, this patch:
1. Removes the requirement that roles define both `users` and
`roles` in impersonate conditions
2. Introduces a new `RoleRequests` field in `UserCertsRequest`
3. Modifies `generateUserCerts` to gather `roles` from
`RoleRequests` if allowed by an `allow` (with no `users`)
[bot]: https://github.com/gravitational/teleport/pull/7986
* Add `determineDesiredRolesAndTraits`; audit log on role impersonation
This splits initial role and trait determination into a new function,
`determineDesiredRolesAndTraits`, to improve control flow and clarity
given the new branches introduced for role impersonation.
Additionally, this moves the call to `CheckRoleImpersonation` down
to match regular user impersonation's flow, and emits an audit log
event on failure.
* Formatting fix
* Unit testing for role requests
This adds a new set of unit tests for role requests.
Also discovered the `impersonator` field wasn't being set for
role impersonation, so it's now set to the user's own username.
In other words, role impersonation will appear (in the audit log and
elsewhere) as self-impersonation.
* Clean up testing users between runs
* Deny most reimpersonation cases and add tests
This attempts to deny most cases of reimpersonation, where an
impersonated certificate might be used to generate certificates for
other roles the user is allowed to impersonate.
One test case is currently failing pending a solution.
* Add new DisallowReissue certificate extension
This adds a new DisallowReissue certificate extension that, if set,
prevents that identity from interacting with `GenerateUserCerts`.
This flag is always set when RoleRequests are used to prevent
unintended privilege escalation (while avoiding breaking changes to
Teleport's existing certificate generation behavior).
* Fix test lints
* Fix typo
* Fix test doc typo, add testcase for user impersonation misuse
* Apply suggestions from code review
Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com>
* Accept context in CreateRole per review feedback
* Fix misleading comment
Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com>
Move cache and resourceWatcher watchers from a 10s retry to a jittered backoff retry up to ~1min. Replace the
reconnectToAuthService interval with a retry to add jitter and backoff there as well for when a node restarts due to
changes introduced in #8102.
Fixes#6889.
Implements RFD 45 / "where" conditions for active sessions[1].
In few words, the purpose of the RFD is to allow the creation of roles that
permits users to only join a subset of active sessions (for example, only their
own sessions).
Implementation goes a bit further than the RFD, allowing the conditions to be
applied to `update` and `delete` verbs as well.
Originally implemented by @andrejtokarcik (#8568), tweaks by @codingllama.
[1] https://github.com/gravitational/teleport/blob/master/rfd/0045-ssh_session-where-condition.md
* Implement where conditions for active sessions list/read
* actionWithConditionForList => actionForListWithCondition
* Make Context-exposed sessions follow the RFD API
* Add tests for "where" conditions on active sessions
* Fix typos
* Fix typos and spacing
* Rename "parties" to "participants" in the context session
* Update RFD to reflect PR changes
Update RFD to reflect PR changes
Specifically, mark as implemented and rename `parties` to `participants`.
* Push list authz logic to ServerWithRoles, obsolete cond
* Remove cond from GetSessions signature
* Simplify cast in lib.utils.Fields.GetString
* Add TODO to refactor SearchSessionEvents / stored sessions
Co-authored-by: Andrej Tokarčík <andrej@goteleport.com>
* Add RBAC for Windows desktop access
This commit adds RBAC checks for Windows Desktops as described in
RFD 33 and RFD 34:
- add Windows desktop logins & labels to role definition
- introduce new file config for host labels based on a regexp match
- auth server API performs access checking for Windows desktop resources
- add RDP client callback to authorize the user
- support user/role locks
- respect the client idle timeout setting
Note: in cases where an connection is terminated to to RBAC, the web UI
currently displays "websocket connection failed" because the connection
is closed from the server. We'll need to follow up with a nice error
message for the client side to improve the UX here.
Other changes:
* Remove OSS RBAC migration marked for deletion
* Stop creating a default admin role
* add wildcard desktop access to the preset access role
Updates #7761
This commit contains 2 changes:
1. Rename GenerateServerKeys to GenerateHostCerts.
This is a more accurate name and consistent with the existing
GenerateUserCerts endpoint.
2. Change the request type to include a single role, rather than a
list of roles. We only ever allowed a single role in the list
anyway, so this change will prevent future mis-use of the API.
Note: a side effect of this change is we now have two similar endpoints:
- GenerateHostCert: old API that generates SSH cert only
- GenerateHostCerts: a newer API that generates SSH and TLS certs
To avoid making this change too big, we'll aim to deprecate
GenerateHostCert in the future.
* Require that public TLS and SSH keys are provided to register via token
The original behavior attempted to make providing public keys optional,
and would generate keys if they were not provided. This had several
problems:
- The auth server is generating private keys for nodes and is
potentially able to share them over the network.
- The return value for keys.Key would sometimes be set and sometimes
be empty (the key is only set if the auth server generated it and
knows what the key is)
- We only ever relied on this behavior as a shortcut in test code.
In the production code this behavior was never used (and actually
never worked due to a bug that would overwrite and discard the
generated private key)
This commit requires that public keys are always provided, ensuring
that the private key is generated locally and never known by the
auth server.
It also results in a cleaner error message when either or both of the
public keys are missing from the request.
* Address review comments
* Fix tests that relied on certs being generated