Skip to content

Commit

Permalink
Support for Nextstrain CLI's new means of authentication with IdPs
Browse files Browse the repository at this point in the history
Nextstrain CLI will start using OIDC/OAuth2's authorization code flow to
interact with not just AWS Cognito but other IdPs as well (i.e. as used
in other deployments of nextstrain.org).

To support this without hardcoding or onerous user-side configuration,
Nextstrain CLI will start using the standard OIDC configuration
endpoint, /.well-known/openid-configuration, to auto-discover necessary
configuration about both the IdP to talk to and the client it should be.

Terraform changes are deployed to both production and testing as they're
additive and will not impact current CLI auth flow.

Related-to: <nextstrain/private#94>
  • Loading branch information
tsibley committed Nov 21, 2023
1 parent 24d0a31 commit 895d308
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 7 deletions.
43 changes: 42 additions & 1 deletion aws/cognito/clients.tf
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,15 @@ resource "aws_cognito_user_pool_client" "nextstrain-cli" {

name = "nextstrain-cli"

# Allow Secure Remote Password (SRP) auth, plus refresh token auth (required).
# Allow client to use OAuth (with the authorization code grant type only)
# against the user pool, plus Secure Remote Password (SRP) auth and refresh
# token auth (required).
allowed_oauth_flows_user_pool_client = true
allowed_oauth_flows = ["code"]
allowed_oauth_scopes = ["email", "openid", "phone", "profile"]

supported_identity_providers = ["COGNITO"]

explicit_auth_flows = [
"ALLOW_USER_SRP_AUTH",
"ALLOW_REFRESH_TOKEN_AUTH",
Expand All @@ -96,6 +104,39 @@ resource "aws_cognito_user_pool_client" "nextstrain-cli" {
refresh_token = "days"
}

# Allowed redirection destinations to complete authentication.
#
# We'd prefer to use 127.0.0.1 instead of localhost to avoid name resolution
# issues on end user systems, issues which are known to occur. The "OAuth
# 2.0 for native apps" best current practice (RFC 8252) suggests as much¹, but
# alas, Cognito's https-requirement exception for localhost is not applied to
# 127.0.0.1.
#
# Similarly, we'd prefer to register without an explicit port and rely on the
# same RFC's stipulation of relaxed port matching for localhost², but alack,
# Cognito doesn't follow that either and requires strict port matching.
#
# Since the CLI may not always be able to listen on a specific port given
# other services that might be running, and there's also value in random
# choice making interception harder, register a slew of ports for use and let
# Nextstrain CLI draw from the list.
# -trs, 19 Nov 2023
#
# ¹ <https://datatracker.ietf.org/doc/html/rfc8252#section-8.3>
# ² <https://datatracker.ietf.org/doc/html/rfc8252#section-7.3>
callback_urls = formatlist("http://localhost:%d/", random_integer.nextstrain_cli_callback_port[*].result)

read_attributes = local.user_attributes
write_attributes = setsubtract(local.user_attributes, ["email_verified", "phone_number_verified"])
}

resource "random_integer" "nextstrain_cli_callback_port" {
# AWS Cognito supports 100 callback URLs per client
# <https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html#resource-quotas>
count = 99

# IANA-defined port range for dynamic use.
# <https://datatracker.ietf.org/doc/html/rfc6335#section-6>
min = 49152
max = 65535
}
4 changes: 4 additions & 0 deletions aws/cognito/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ output "OAUTH2_CLI_CLIENT_ID" {
value = aws_cognito_user_pool_client.nextstrain-cli.id
}

output "OAUTH2_CLI_CLIENT_REDIRECT_URIS" {
value = aws_cognito_user_pool_client.nextstrain-cli.callback_urls
}

output "OAUTH2_LOGOUT_URL" {
value = format("https://%s/logout", coalesce(
one(aws_cognito_user_pool_domain.custom[*].domain),
Expand Down
34 changes: 28 additions & 6 deletions docs/production.rst
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ file are::
OAUTH2_CLIENT_ID
OAUTH2_CLIENT_SECRET
OAUTH2_CLI_CLIENT_ID
OAUTH2_CLI_CLIENT_REDIRECT_URIS
OIDC_USERNAME_CLAIM
OIDC_GROUPS_CLAIM

Expand Down Expand Up @@ -282,13 +283,34 @@ CLI client
A `public, native application client <oauth2-clients_>`__ is required for use
by the :doc:`Nextstrain CLI <cli:index>` and is permitted by the app server to
make `Bearer`-authenticated requests. Its id is configured by
`OAUTH2_CLI_CLIENT_ID`.
`OAUTH2_CLI_CLIENT_ID`. The client registration must allow:

.. note::
Currently Nextstrain CLI is tightly bound to AWS Cognito and requires
its Secure Remote Password authentication flow implemented outside of
the standard OAuth 2.0 flows. We anticipate changing this in the
future.
- the authorization code flow, ideally with PKCE_ support

- issuance of refresh tokens, either by default or by requesting the
`offline_access` scope

- at least one authentication redirection (sometimes "callback") URL of
`http://127.0.0.1:<port>/` or `http://localhost:<port>/`

The CLI auto-discovers its OpenID client configuration (and the IdP
configuration) from the app server. The app server must be configured to know
the CLI client's redirect URIs with `OAUTH2_CLI_CLIENT_REDIRECT_URIS` so the
URLs can be included in the discovery response.

If the IdP allows for `http://` redirect URIs for loopback IPs (e.g.
`127.0.0.1`), then the loopback IP should be preferred over using `localhost`,
as per best current practice described in `RFC 8252 § 8.3`_.

If the IdP allows relaxed port matching for loopback IP/localhost redirect
URIs, as per best current practice described in `RFC 8252 § 7.3`_, then only a
single redirect URI needs to be registered with the IdP. Otherwise, multiple
redirect URIs with varying ports should be registered to allow the CLI
alternatives to choose from in case it can't bind a given port on a user's
computer.

.. _RFC 8252 § 7.3: https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
.. _RFC 8252 § 8.3: https://datatracker.ietf.org/doc/html/rfc8252#section-8.3


Token lifetimes
Expand Down
4 changes: 4 additions & 0 deletions env/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ output "OAUTH2_CLI_CLIENT_ID" {
value = module.cognito.OAUTH2_CLI_CLIENT_ID
}

output "OAUTH2_CLI_CLIENT_REDIRECT_URIS" {
value = module.cognito.OAUTH2_CLI_CLIENT_REDIRECT_URIS
}

output "OAUTH2_LOGOUT_URL" {
value = module.cognito.OAUTH2_LOGOUT_URL
}
Expand Down
19 changes: 19 additions & 0 deletions env/production/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions env/production/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,107 @@
"OIDC_IDP_URL": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Cg5rcTged",
"OAUTH2_CLIENT_ID": "rki99ml8g2jb9sm1qcq9oi5n",
"OAUTH2_CLI_CLIENT_ID": "2vmc93kj4fiul8uv40uqge93m5",
"OAUTH2_CLI_CLIENT_REDIRECT_URIS": [
"http://localhost:49154/",
"http://localhost:49208/",
"http://localhost:49233/",
"http://localhost:49278/",
"http://localhost:49852/",
"http://localhost:50049/",
"http://localhost:50146/",
"http://localhost:50208/",
"http://localhost:50290/",
"http://localhost:50552/",
"http://localhost:50555/",
"http://localhost:50560/",
"http://localhost:50978/",
"http://localhost:51122/",
"http://localhost:51182/",
"http://localhost:51357/",
"http://localhost:51494/",
"http://localhost:51716/",
"http://localhost:51838/",
"http://localhost:51841/",
"http://localhost:51861/",
"http://localhost:51924/",
"http://localhost:52109/",
"http://localhost:52176/",
"http://localhost:52191/",
"http://localhost:52258/",
"http://localhost:52560/",
"http://localhost:52629/",
"http://localhost:53113/",
"http://localhost:53369/",
"http://localhost:53995/",
"http://localhost:54137/",
"http://localhost:54211/",
"http://localhost:54378/",
"http://localhost:54568/",
"http://localhost:54971/",
"http://localhost:55027/",
"http://localhost:55341/",
"http://localhost:55396/",
"http://localhost:55535/",
"http://localhost:55536/",
"http://localhost:55555/",
"http://localhost:55610/",
"http://localhost:55825/",
"http://localhost:56014/",
"http://localhost:56361/",
"http://localhost:56691/",
"http://localhost:56846/",
"http://localhost:56978/",
"http://localhost:57264/",
"http://localhost:57282/",
"http://localhost:57578/",
"http://localhost:57856/",
"http://localhost:57875/",
"http://localhost:58039/",
"http://localhost:58199/",
"http://localhost:58638/",
"http://localhost:59095/",
"http://localhost:59462/",
"http://localhost:59507/",
"http://localhost:59628/",
"http://localhost:59804/",
"http://localhost:59906/",
"http://localhost:59942/",
"http://localhost:60139/",
"http://localhost:60257/",
"http://localhost:60377/",
"http://localhost:60564/",
"http://localhost:60579/",
"http://localhost:60705/",
"http://localhost:60775/",
"http://localhost:61015/",
"http://localhost:61309/",
"http://localhost:61376/",
"http://localhost:61384/",
"http://localhost:61399/",
"http://localhost:61588/",
"http://localhost:61915/",
"http://localhost:62350/",
"http://localhost:62478/",
"http://localhost:62752/",
"http://localhost:62947/",
"http://localhost:63087/",
"http://localhost:63124/",
"http://localhost:63230/",
"http://localhost:63257/",
"http://localhost:63514/",
"http://localhost:63519/",
"http://localhost:63638/",
"http://localhost:63692/",
"http://localhost:63838/",
"http://localhost:64029/",
"http://localhost:64098/",
"http://localhost:64294/",
"http://localhost:64873/",
"http://localhost:65081/",
"http://localhost:65266/",
"http://localhost:65271/",
"http://localhost:65311/"
],
"OAUTH2_LOGOUT_URL": "https://login.nextstrain.org/logout",
"COGNITO_USER_POOL_ID": "us-east-1_Cg5rcTged",
"OIDC_USERNAME_CLAIM": "cognito:username",
Expand Down
19 changes: 19 additions & 0 deletions env/testing/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 100 additions & 0 deletions env/testing/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,106 @@
"OIDC_IDP_URL": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_zqpCrjM7I",
"OAUTH2_CLIENT_ID": "6qiojrhr8tibt0f6hphnm1osp1",
"OAUTH2_CLI_CLIENT_ID": "9opa27o74f4jsq8g4a34e1mqr",
"OAUTH2_CLI_CLIENT_REDIRECT_URIS": [
"http://localhost:49161/",
"http://localhost:49334/",
"http://localhost:49359/",
"http://localhost:49398/",
"http://localhost:49603/",
"http://localhost:50044/",
"http://localhost:50110/",
"http://localhost:50132/",
"http://localhost:50467/",
"http://localhost:50667/",
"http://localhost:50712/",
"http://localhost:51264/",
"http://localhost:51333/",
"http://localhost:51413/",
"http://localhost:51467/",
"http://localhost:51596/",
"http://localhost:51664/",
"http://localhost:51953/",
"http://localhost:51974/",
"http://localhost:51977/",
"http://localhost:52272/",
"http://localhost:52342/",
"http://localhost:52361/",
"http://localhost:52564/",
"http://localhost:52621/",
"http://localhost:52673/",
"http://localhost:53216/",
"http://localhost:53267/",
"http://localhost:53375/",
"http://localhost:53624/",
"http://localhost:53644/",
"http://localhost:54071/",
"http://localhost:55078/",
"http://localhost:55286/",
"http://localhost:55296/",
"http://localhost:55357/",
"http://localhost:55419/",
"http://localhost:55462/",
"http://localhost:55724/",
"http://localhost:56972/",
"http://localhost:57135/",
"http://localhost:57194/",
"http://localhost:57255/",
"http://localhost:57321/",
"http://localhost:57411/",
"http://localhost:57564/",
"http://localhost:57591/",
"http://localhost:57649/",
"http://localhost:57654/",
"http://localhost:57883/",
"http://localhost:58259/",
"http://localhost:58549/",
"http://localhost:58826/",
"http://localhost:59071/",
"http://localhost:59359/",
"http://localhost:59688/",
"http://localhost:60055/",
"http://localhost:60107/",
"http://localhost:60205/",
"http://localhost:60590/",
"http://localhost:60790/",
"http://localhost:60883/",
"http://localhost:60897/",
"http://localhost:60911/",
"http://localhost:61155/",
"http://localhost:61325/",
"http://localhost:61369/",
"http://localhost:61400/",
"http://localhost:61406/",
"http://localhost:61553/",
"http://localhost:62190/",
"http://localhost:62405/",
"http://localhost:62439/",
"http://localhost:62467/",
"http://localhost:62638/",
"http://localhost:62726/",
"http://localhost:63016/",
"http://localhost:63103/",
"http://localhost:63309/",
"http://localhost:63318/",
"http://localhost:63387/",
"http://localhost:63480/",
"http://localhost:63526/",
"http://localhost:63704/",
"http://localhost:63743/",
"http://localhost:63775/",
"http://localhost:64008/",
"http://localhost:64373/",
"http://localhost:64410/",
"http://localhost:64446/",
"http://localhost:64520/",
"http://localhost:64694/",
"http://localhost:64960/",
"http://localhost:64972/",
"http://localhost:65032/",
"http://localhost:65086/",
"http://localhost:65113/",
"http://localhost:65121/"
],
"OAUTH2_LOGOUT_URL": "https://nextstrain-testing.auth.us-east-1.amazoncognito.com/logout",
"COGNITO_USER_POOL_ID": "us-east-1_zqpCrjM7I",
"OIDC_USERNAME_CLAIM": "cognito:username",
Expand Down
Loading

0 comments on commit 895d308

Please sign in to comment.