rafiki icon indicating copy to clipboard operation
rafiki copied to clipboard

design auth mechanism for admin UI

Open sabineschaller opened this issue 2 years ago • 7 comments

sabineschaller avatar Nov 20 '23 13:11 sabineschaller

To consider: Auth0 Okta keycloak hydra

JoblersTune avatar Dec 01 '23 07:12 JoblersTune

Ory Hydra is completely open source (I think) so that should be top of the list.

sabineschaller avatar Dec 04 '23 09:12 sabineschaller

NOTE: This current status is very much in a rough draft showing off my experiments at the moment. I will update it as things progress.

Advantages of Ory/Hydra

  • strictly adheres to OAuth 2.0 and OpenID Connect standards
  • lightweight and efficient solution for token management, which is nice for a microservices architecture
  • Big focus on best security practices
  • Ory has an active community
  • Open Source and transparent

Approach

  • implement a secure and standardized authorization code flow
  • I believe we can skip the consent step in the proccess for user login (though I think Ory insists on not skipping it for first sign on)
  • Currently just using the idea of a full_access scope

Current Progress

  • Check out my branch: sj/2200-admin-ui-auth
  • Hydra is running in a Docker container, connected to a locally hosted PostgreSQL database
  • I've performed necessary database setups and migrations for Hydra
  • An OAuth2 client for the Rafiki admin has been created, configured for the authorization code flow
  • Additionally, I've implemented a basic dummy flow in our admin UI

Next Steps

  • Finish managing the consent flow
  • Consider what scopes to use
  • Consider what user roles are required
  • Exploring Ory Kratos Integration for the user identity management
  • Get the Admin UI to correctly handle and validate the authentication tokens provided by Hydra
  • Consider how this approach would align with securing the API calls - I think this will align well since we have granular control over what scopes users consent to which should align with our GNAP approach
  • Get this all properly containerized in a docker-compose file

JoblersTune avatar Jan 23 '24 06:01 JoblersTune

Note: I'm updating this document to reflect the current status:

Local Playground (Preferred setup)

pnpm localenv:compose up And in the browser simply go to http://localhost:4444/oauth2/auth?response_type=code&client_id=cloud-nine-client&redirect_uri=http://localhost:3010/callback&scope=full_access&state=ab4R32wFF

Local Set Up

First set up the hydra database, e.g. in Postgresql sudo -i -u postgres psql CREATE USER hydra WITH PASSWORD 'hydra_password'; CREATE DATABASE hydra; GRANT ALL PRIVILEGES ON DATABASE hydra TO hydra; exit Run the db migrations docker run -it --rm \ --network="host" \ oryd/hydra \ migrate sql --yes postgres://hydra:hydra_password@localhost:5432/hydra"

Get the ory hydra docker container up

docker run --network="host" --name ory-hydra -e DSN=postgres://hydra:hydra_password@localhost:5432/hydra -e URLS_SELF_ISSUER=http://localhost:4444/ -e URLS_LOGIN=http://localhost:3005/login -e URLS_CONSENT=http://localhost:3005/consent -e SECRETS_SYSTEM=some-random-secret -e LOG_LEVEL=debug -e LOG_LEAK_SENSITIVE_VALUES=true oryd/hydra serve all -
-dev

Add client to the db docker exec -it ory-hydra /bin/sh

hydra create oauth2-client --grant-type authorization_code --name rafiki-admin-client --redirect-uri http://localhost:3005 --response-type code --scope full_access --secret YourClientSecret --skip-consent --token-endpoint-auth-method client_secret_post --endpoint http://localhost:4445

This will give you a CLIENT ID. TO DO: Add this client ID as an environment variable to HYDRA_CLIENT_ID Set HYDRA_CLIENT_REDIRECT_URI to http://localhost:3005 Set SEED_FILE_LOCATION to packages/frontend/app/seed.yml Create the seed.yml file with your client's ID

clients:
- id: 'YOUR_CLIENT_ID'
  name: 'happy-life'
  redirectUri: 'http://localhost:3005/callback'

Start the frontend in dev mode - pnpm --filter frontend dev Then enter this URL into a browser with your CLIENT_ID: http://localhost:4444/oauth2/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=http://localhost:3005&scope=full_access&state=ab4R32wFF

JoblersTune avatar Jan 23 '24 08:01 JoblersTune

@JoblersTune Is there any other setup that needs to be done on the postgres instance? I had to manually create the hydra database and the hydra_user user but I'm stuck on what table it's looking for when it throws Unable to locate the table - I'm not sure what table I should try to insert:

level=error msg=Unable to initialize service registry. audience=application error=map[debug: message:Unable to locate the table reason: status:Internal Server Error status_code:500] service_name=Ory Hydra service_version=v2.2.0-rc.3

edit: this is happening when I run the first command in the Set up post.

njlie avatar Jan 23 '24 20:01 njlie

My db set up was like this: sudo -i -u postgres psql CREATE USER hydra_user WITH PASSWORD 'x@mpl3_p@ssw0rd'; CREATE DATABASE hydra; GRANT ALL PRIVILEGES ON DATABASE hydra TO hydra_user; exit docker run -it --rm \ --network="host" \ oryd/hydra \ migrate sql --yes "postgres://hydra_user:x@mpl3_p@ssw0rd@localhost:5432/hydra"

I'll update the initial setup comment to be explicit.

If this doesn't resolve your issue then let me know.

JoblersTune avatar Jan 24 '24 13:01 JoblersTune

Auth Flow

  1. Initial request to Hydra's authorization endpoint (http://hydra:4444/oauth2/auth) to start the OAuth flow with the necessary query parameters (response_type, client_id, redirect_uri and scope)
  • The hydra instance write some cookies to the browser
  • The hydra instance creates a session for the interaction
  1. The browser is redirected to the client's login provider with a login_challenge (should be Kratos but for now is http://localhost:3010/login). This is where the user will authenticate.
  • The admin remix server calls the Hydra server using the cookies and identifiers for the session to get session information and set up the interaction on the front end
  1. Redirect after successful authentication to Hydra's admin endpoint to accept the login request (http://hydra:4445/admin/oauth2/auth/requests/login/accept) along with the login_challenge.
  2. If the login challenge is completed successfully, the remix server redirects the browser to its a configured consent endpoint which was registered with the client where the user can approve the requested permissions. This is accompanied by a consent_challenge.
  • The admin remix server calls the Hydra server using the cookies and identifiers for the session to get session information and set up the interaction on the front end
  1. After consent is granted the Remix server indicates that to the Hydra's admin endpoint (http://hydra:4445/admin/oauth2/auth/requests/consent/accept) along with the consent_challenge.
  2. The browser is redirected to the client's configured callback URL with authorization code in the query parameters.
  3. The callback page handles the result of the consent and if it received an authorization code it exchanges it for an access token at Hydra's authorization endpoint (http://hydra:4444/oauth2/token)

JoblersTune avatar Feb 12 '24 11:02 JoblersTune