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

Passwordless support #9160

Closed
codingllama opened this issue Nov 29, 2021 · 4 comments
Closed

Passwordless support #9160

codingllama opened this issue Nov 29, 2021 · 4 comments
Assignees
Labels
feature-request Used for new features in Teleport, improvements to current should be #enhancements

Comments

@codingllama
Copy link
Contributor

codingllama commented Nov 29, 2021

What

Users can login using strong, presence-and-verification-capable authenticators instead of passwords (Touch ID, biometric keys, etc).

This is an umbrella issue for the passwordless work, including RFD, backend and CLI changes. Web UI likely to be tracked elsewhere.

How

See the Passwordless RFDs for local authentication:

Why

Passwordless is the state-of-the-art for both security and usability.

Workaround

Type your passwords forever.

@codingllama codingllama added the feature-request Used for new features in Teleport, improvements to current should be #enhancements label Nov 29, 2021
@codingllama codingllama self-assigned this Nov 29, 2021
@codingllama
Copy link
Contributor Author

codingllama commented Feb 3, 2022

Tasks related to RFD 52 - at the end it should be (theoretically) possible to do passwordless authentication via browser.

Web UI tasks are not tracked in this issue - see #10249 instead.

Server-side changes

  • Support global, queryable WebAuthn user handles
  • Record additional information in types.WebAuthnDevice
  • Global challenge / SessionData storage
  • lib.auth.webauthn allows passwordless authentication
  • lib.auth.webauthn registers passwordless devices
  • Basic rate-limiting for authentication APIs
  • Authentication API changes (Auth)
  • Authentication API changes (Proxy)
  • Registration API changes (Auth)
  • Registration API changes (Proxy)
  • (Optional) Simple Web prototype that registers/authenticates using passwordless

Tail end tasks, not necessary for core functionality:

Documentation

  • Write public-facing docs
  • Update RFDs

@codingllama
Copy link
Contributor Author

codingllama commented Feb 3, 2022

Tasks related to RFD 53 - at the end tsh supports both FIDO2 and passwordless (Linux and macOS).

Solves #8499.

tsh FIDO2

  • lib.auth.webauthncli FIDO2 authentication (MFA)
  • lib.auth.webauthncli FIDO2 authentication (passwordless)
  • lib.auth.webauthncli FIDO2 registration (MFA)
  • lib.auth.webauthncli FIDO2 registration (passwordless)
  • Deterministic builds using FIDO2 (see below)
  • Refactor/Wire FIDO2 into the existing webauthncli MFA flows (Login and Register)
  • tsh login --pwdless
  • tsh mfa add supports passwordless registration

Tail end tasks:

  • PIN registration during tsh mfa add
  • Show passwordless status in tsh mfa ls (needs UX discussion)

FIDO2 authentication includes the flow described at rfd/0053-passwordless-fido2.md#cli-native-authentication. It supports both PIN and biometric devices.

FIDO2 registration includes initial PIN setup.

FIDO2 builds

  • Linux / amd64
  • Linux / arm64
  • macOS / amd64
  • macOS / arm64

@codingllama
Copy link
Contributor Author

codingllama commented Feb 3, 2022

Tasks related to RFD 54 - at the end tsh supports passwordless using Touch ID on macOS.

tsh Touch ID

  • lib.auth.touchid registration
  • lib.auth.touchid authentication (MFA/passwordless)
  • lib.auth.touchid detect support / diagnostics
  • lib.auth.touchid list credentials
  • lib.auth.touchid delete credential
  • Touch ID example/test binary
  • Wire Touch ID into lib.auth.webauthncli flows
  • tsh global flags (--mfa_mode)
  • tsh signature+entitlement setup
  • tsh touchid diag
  • tsh touchid list
  • tsh touchid delete
  • Setup for the macOS tsh.app
  • Build pipeline changes for tsh macOS release

lib.auth.touchid is a mix of Go and ObjC.

Example/test binary is used to make sure we can exercise the code outside of tsh. Because we are reliant on both system calls and entitlements, it's difficult to test or run the code without a support binary.

codingllama added a commit that referenced this issue Feb 14, 2022
Introduces webauthn.User (for usernameless logins) and extends
webauthn.SessionData and types.WebauthnDevice with relevant fields.

#9160

* Add passwordless-related information to protos
* Add missing field tags
* Update generated protos
* Reformat protos (make grpc)
codingllama added a commit that referenced this issue Feb 14, 2022
Global session data is used to store passwordless challenges. Per-user session
data cannot be used, as the user is now known by the time the challenge is
issued.

I elected to keep both global and per-user session data storage for now, as
per-user is less subject to DDoS-type attacks than global.

#9160
codingllama added a commit that referenced this issue Feb 22, 2022
Used to discover the Teleport user in usernameless logins.

#9160

* Index and read user by WebAuthn user ID
* Use Wrap instead of WrapWithMessage
* Refactor newIdentityService so return looks more natural
* Use base64.RawURLEncoding to encode challenge keys
* Attempt to rollback first write on failure
codingllama added a commit that referenced this issue Feb 22, 2022
)

I've opted to keep MFA and passwordless authorization interfaces separate, as
they have slight interface differences, storage needs, and allow for different
use-cases.

LoginFlow, the existing API, is now focused on MFA. A new type,
PasswordlessFlow, provides support for passwordless authorization. Both
implementations are backed by a private loginFlow type, refactored from the guts
of the old LoginFlow, which is a superset of MFA and Passwordless.

All registration use-cases are provided by the existing RegistrationFlow. In
this case the change is simpler, as a single passwordless parameter suffices.
Registration is always performed by a previously-authorized user, so it's
storage interactions remain uniform.

Finally, login methods won't create a WebAuthn ID anymore, instead they rely on
registration to do it. The simplification relies on the fact that user handles
are not mandatory. (They do matter for resident key registration, which does
provide them.)

#9160

* Add verification support to mocku2f
* Support passwordless login on lib/auth/webauthn
* Support passwordless registration on lib/auth/webauthn
* Refactor web ID creation
codingllama added a commit that referenced this issue Feb 23, 2022
Limits the number of in-flight challenges by counting the number of stored
global SessionData instances.

It's important to limit the number of global challenges because they are
requested by anonymous users.

#9160

* Limit number of in-flight passwordless challenges
* Use a local counter to keep track of challenges
codingllama added a commit that referenced this issue Mar 3, 2022
Passwordless endpoints are rate limited because they allow unauthenticated
challenge generation. The endpoint rate limits are applied in addition to
(pre-existing) storage limits.

Setting limits to Auth only would be sufficient, but it seems best to apply
limits to Proxy as well, so we may spare Auth of unnecessary load.

Auth already has a framework for RPC rate limiting, so we took advantage of it.
The solution for the Proxy is rather simple - the handler is decorated with the
appropriate limits.

#9160

* Fix shadowing of grpcServer variable
* Add rate limiting for CreateAuthenticateChallenge
* Add rate limiting for /mfa/login/begin
* Safe parallel tests
codingllama added a commit that referenced this issue Mar 4, 2022
Wire passwordless registration and authorization into Auth and Proxy APIs, thus
making passwordless logins possible.

API changes are described by RFD 52: Passwordless [1].

#9160

[1] https://github.com/gravitational/teleport/blob/master/rfd/0052-passwordless.md#authentication-api-changes

* Add passwordless settings to Auth protos
* Update generated protos
* Register: Apply DeviceUsage in lib/auth
* Register: Apply DeviceUsage in lib/web
* Login: Generate passwordless challenge
* Login: Allow passwordless authentication
* Wire passwordless in lib/web endpoints
* Make mocku2f passwordless setup a bit nicer
codingllama added a commit that referenced this issue Mar 18, 2022
Implements CLI login and registration using go-libfido2. Covers both MFA and
passwordless use cases.

The FIDO2 implementation is akin to the existing U2F Login / Registration logic,
including a similar "device detection" loop. A few notable differences are:

A filtered "device search" step that ends as soon a suitable device is found A
more explicit "device selection" step, which makes it easier to implement PIN
flows The MFA UX for end-users should remain mostly unaltered.

There are no separate methods for MFA and passwordless, as much of the logic
would be the same. Instead, the methods react to the assertion/credential
parameters accordingly.

At this moment this code is isolated from other callers, as well as from our
build processes via the libfido2 tag. This is to avoid impact to other
developers, as go-libfido2 has a few requirements before it can be downloaded or
executed.

#9160

* Import github.com/keys-pub/go-libfido2
* Implement FIDO2 login
* Add login tests
* Implement FIDO2 registration
* Add registration tests
codingllama added a commit that referenced this issue Mar 21, 2022
Seamlessly change the public API of lib/auth/webauthncli to use the
libfido2-backed implementation, as long as the binary was compiled with the
libfido2 build tag.

A few adjustments are necessary to "wancli" methods to allow users to provide
prompt callbacks and to return the credential user (not applicable here, but
will be in following PRs).

Additional changes are made to tsh mfa add in order to avoid stdin hijacking by
ContextReader, since we now may require PIN reads for authenticators.

#9160

* Move U2F logic to u2f_* files
* Split U2F API from general l/a/webauthncli API
* Move FIDO2 public API to fido2_common.go, introduce IsFIDO2Available
* Introduce prompt.SyncReader

Sync reads allow prompt calls to be mixed with term.ReadPassword calls.

* Wire FIDO2 into MFA login
* Wire FIDO2 into MFA registration
codingllama added a commit that referenced this issue Mar 23, 2022
Passwordless login is enabled by the global `--pwdless` flag. Registration gets
a new prompt and an `--allow-passwordless` flag.

UX messages were tweaked to follow the descriptions on RFD 53: Passwordless
FIDO2[1].

Passwordless login requires two touches for all devices (both PIN and biometric).
I'd like to get it down to a single touch, at least for the most common
situations, but that'll be a follow up to this work.

Passwordless support requires `tsh` to be compiled with the `libfido2` tag, try
`go build -tags=libfido2 ./tool/tsh`.

#9160

[1] https://github.com/gravitational/teleport/blob/master/rfd/0053-passwordless-fido2.md#ux

* Allow reuse of devices for passwordless
* Implement passwordless registration in tsh
* Add better tracing to FIDO2 filters
* Implement passwordless logins in tsh
* Make --pwdless a global flag
* Fix lint errors
* Fix U2F tests
* Use initClient's URL as origin
* Distinguish whether --allow-passwordless is set or unset
codingllama added a commit that referenced this issue May 11, 2022
Implement touch ID credential management via tsh touchid ls and tsh touchid rm.

Departs slightly from RFD command names in order to better match the tsh mfa.

See https://github.com/gravitational/teleport/blob/master/rfd/0054-passwordless-macos.md.

#9160

* Implement touch ID credential listing
* Add the `tsh touchid ls` command
* Implement touch ID credential deletion
* Add the `tsh touchid rm` command
* Delegate MFA prompts to WebAuthn
* Undo changes to tsh.go command switch
* Prompt newline. Trace errors.
* Update e/ to 6abb96b
* Var initialization. Guard against NULL. Return all credentials.
* Address review comments: simplifications and style
codingllama added a commit that referenced this issue May 23, 2022
Changes how `make pkg-tsh` works so instead of building an installer for the
`tsh` binary, placed under `/usr/local/bin`, we install an app to
`/Applications/tsh-vXXX.app` and link its `tsh` binary to `/usr/local/bin`.

The app shell is necessary to distribute a provisioning profile along with the
signed/entitled/notarized binary. All of that is required for Touch ID to work.
Naked `tsh` binaries are unable to use Touch ID, even if built with the correct
build tags.

I've elected to split the logic from `build-package.sh` into a separate script -
it already does too much as-is. `build-pkg-tsh.sh` is more idiomatic, clears
additional `shellcheck` rules and is easier to dry-run.

#9160

* Build macOS installer for tsh.app
* Add resources to build the tshdev app
Moved from e/

* Add resources to build the tsh app (prod)
* Use production values
* Remove 'tsh' mode from build-package.tsh
* Appease buildbox linter
* Clarify one-time setup
codingllama added a commit that referenced this issue May 24, 2022
Adding a "marker" to Keychain labels lets us detect unexpected entries (which I
did see happen) and gives us flexibility to change formats in the future.

A marker in the "label" field seems to be enough to achieve the purposes above,
so I stopped at that. Added a couple minor UX tweaks as well.

#9160

* Use a marker for Keychain labels
* Tweak: Rename "Key Handle" to "Credential ID" for consistency
* Tweak: Do not prompt MFA/OTP if doing Touch ID
* Use trace errors
codingllama added a commit that referenced this issue May 25, 2022
Add the TOUCHID=yes Makefile toggle and enable it on Drone.

Complements #12751.

#9160

* Enable touchid builds on Drone
* Update Drone URL in error message
* Run `make dronegen`
codingllama added a commit that referenced this issue May 31, 2022
Add a script to build libfido2 (and its dependencies) on macOS and enable FIDO2
static builds.

I decided to build all dependencies instead of pulling from Homebrew for a few
reasons:

1. There is no libcbor.a in a brew package
2. This captures library versions within the Teleport source code, allowing us
   to build binaries against different versions of libfido2 (and its
   dependencies).

I've also bumped libfido2 to 1.11.0. I've been running it locally and we are
still pre-release, so it seems like a good time to do it.
(See https://developers.yubico.com/libfido2/Release_Notes.html.)

#9160

* Build libfido2 and dependencies for macOS
* Build tsh with static fido2 on Drone
* Bump libfido2 versions in all builds
* Attempt to appease linters
* Use temp dirs inside LIB_CACHE
* Move LIB_CACHE outside of HOME

HOME is reassigned in macOS builders, but we want a "stable" cache
directory. /tmp is used by build-package.sh and build-pkg-tsh.sh.

* Rename script to build-fido2-macos.sh
* Regenerate Drone files
codingllama added a commit that referenced this issue May 31, 2022
Since #12794 we now build `tsh` binaries with touch ID capabilities. This calls
for a more sophisticated mechanism to determine if touch ID functions should be
enabled, as compile-time support only is not enough.

I've added the following checks, on top of compile-time / `touchid` build tag:

Binary is signed
Binary has entitlements
Machine is touch ID capable
Machine has a Secure Enclave
Put together this give us a much better proxy on whether to enable touch ID.

I've also added the `tsh touchid diag` command, mentioned in the Passwordless
macOS RFD (see
https://github.com/gravitational/teleport/blob/master/rfd/0054-passwordless-macos.md#tsh-support-commands).

#9160

* Improved touch ID availability and diagnostics
* Add the `tsh touchid diag` command
* Set min macOS version to 10.12 (macOS Sierra)
codingllama added a commit that referenced this issue Jun 2, 2022
Set the macOS deployment target, ensuring that statically linked libfido2 `tsh`
builds run correctly on older macOS versions.

#9160

* Consistently set macOS min version
* Bump min macOS version to 10.13
codingllama added a commit that referenced this issue Jun 3, 2022
Icons file generated using a 512x512 base image and `makeicns`.

#9160
codingllama added a commit that referenced this issue Jun 8, 2022
Change the Touch ID registration interface so `tsh` explicitly confirms or
rollbacks MFA registrations.

Before resident keys, MFA keys from U2F or WebAuthn only truly existed
server-side, but with resident keys/passwordless some cleanup is necessary if
the server-side registration goes awry.

The PR also changes Touch ID authentication so that newer keys are preferred,
which allows re-registration to be used as sort of a self-healing mechanism.

#9160

* Read creation time from Keychain entries
* Explicitly confirm or rollback Touch ID registrations
@codingllama
Copy link
Contributor Author

The last few documentation updates are out and there is more than enough here to call this done, so that's what I'm doing. 🎉

The passwordless preview, soon to be released, lacks a few features that were present in the design. Specifically:

  • Built-in passwordless roots for Teleport (cut because it actually breaks Touch ID in most scenarios)
  • FIDO2 PIN setup during tsh mfa add (cut because it's non-essential, delicate and probably better done with the manufacturer's software)

At this moment we are also lacking arm64 and Windows support. I'll track those and other upcoming work separately.

codingllama added a commit that referenced this issue Jun 9, 2022
Mark RFDs as implemented and do some minor updates to reflect implementation
changes.

#9160
codingllama added a commit that referenced this issue Jul 6, 2022
Add a batch of public documentation changes that cover:

* Passwordless (new guide and various links)
* WebAuthn updates in regards to U2F
* U2F documentation removal (superseded by WebAuthn)
* Updated config reference (`teleport.yaml` and equivalents)
* Updated `tsh` reference

This should cover the bulk of the work under Passwordless (#9160) and U2F sunset (#10375).

#9160

Co-authored-by: Paul Gottschling <[email protected]>
codingllama added a commit that referenced this issue Jul 6, 2022
Add a batch of public documentation changes that cover:

* Passwordless (new guide and various links)
* WebAuthn updates in regards to U2F
* U2F documentation removal (superseded by WebAuthn)
* Updated config reference (`teleport.yaml` and equivalents)
* Updated `tsh` reference

This should cover the bulk of the work under Passwordless (#9160) and
U2F sunset (#10375).

Co-authored-by: Paul Gottschling <[email protected]>
codingllama added a commit that referenced this issue Jul 6, 2022
…4163)

Add/update docs for passwordless, WebAuthn and U2F (#13314)

Add a batch of public documentation changes that cover:

* Passwordless (new guide and various links)
* WebAuthn updates in regards to U2F
* U2F documentation removal (superseded by WebAuthn)
* Updated config reference (`teleport.yaml` and equivalents)
* Updated `tsh` reference

This should cover the bulk of the work under Passwordless (#9160) and
U2F sunset (#10375).

Co-authored-by: Paul Gottschling <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Used for new features in Teleport, improvements to current should be #enhancements
Projects
None yet
Development

No branches or pull requests

1 participant