Skip to content

Feat/create app client generation script #921

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 33 additions & 38 deletions backend/compact-connect/app_clients/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
# App Client Management for Staff Users

## Overview
This document is a guide for technical staff for managing Cognito app clients for machine-to-machine authentication in the Staff Users pool. All app clients must be documented in yaml files in the `/app_clients` directory for disaster recovery purposes (ie a deployment error or AWS region outage causes app client data to be lost so it must be recreated). See the example app client for the format.
This document is a guide for technical staff for managing Cognito app clients for machine-to-machine authentication in the Staff Users pool. All app clients must be documented in the external 'Compact Connect App Client Registry' Google Sheet (If you do not have access to said registry, contact a maintainer of the project and request access).

## Creating a New App Client

### 1. Documentation Prerequisites
### 1. Prerequisites
Before creating a new app client, ensure you have:
- Jurisdiction requirements documented
- Jurisdiction requirements documented (compact and state)
- Contact information for the consuming team
- Approval to grant the app client with the requested scopes
- AWS CLI permissions to create app clients for the Staff Users user pool in the needed AWS accounts
- AWS credentials configured with permissions to create app clients for the Staff Users user pool in the needed AWS accounts
- Python 3.6+ installed with boto3 dependency (`pip install boto3`)

### 2. Update Registry
Add a new app client yaml file to `/app_clients` following the schema of the example app client.
Add the new app client information to the external Google Sheet registry for tracking and disaster recovery purposes (ie a deployment error or AWS region outage causes app client data to be lost so it must be recreated).

#### **Scope Configuration**
Scopes are the permissions that the app client will have. There are two tiers of scopes:
Expand Down Expand Up @@ -43,59 +44,53 @@ Add a new app client yaml file to `/app_clients` following the schema of the exa

Currently, the most common scope needed by app clients is the `{jurisdiction}/{compact}.write` scope. This scope allows the app client to upload license data for a jurisdiction/compact combination.

### 3. Create App Client in AWS Using CLI
To create an app client with the needed OAuth scopes configured, you will use the AWS CLI. After logging into the correct AWS account for the us-east-1 region, run the following cli command (for the OAuth scopes, you will put whatever scopes are documented in the yaml file, the following is an example of the format used to define the scopes):
```
aws cognito-idp create-user-pool-client --user-pool-id '<staff users's user pool id>' \
--client-name '<name of client you set in the yaml file, it should include a version suffix for rotation, e.g. "example-ky-app-client-v1">'\
--prevent-user-existence-errors ENABLED \
--generate-secret \
--token-validity-units AccessToken='minutes'\
--access-token-validity 15 \
--allowed-o-auth-flows-user-pool-client \
--allowed-o-auth-flows 'client_credentials' \
--allowed-o-auth-scopes '<compact>/readGeneral' '<jurisdiction>/<compact>.write'
### 3. Create App Client Using Interactive Python Script
**Use the provided Python script in the bin directory for streamlined app client creation:**

```bash
python3 bin/create_app_client.py -e <environment> -u <user_pool_id>
```

This command creates an app client with the ability to generate access tokens that expire after 15 minutes. This expiration time can be adjusted according to the needs of the consuming team up to 1 day (see [AccessTokenValidity](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html#CognitoUserPools-CreateUserPoolClient-request-AccessTokenValidity)), though it is strongly recommended to keep this value as short as possible to limit the amount of time an access token is valid for if it is compromised. The consuming team will need to implement logic to generate new access tokens before previous tokens expire.
**Interactive Process:**
The script will prompt you for:
- App client name (e.g., "example-ky-app-client-v1")
- Compact (aslp, octp, coun)
- State postal abbreviation (e.g., "ky", "la")
- Additional scopes (optional)

If the consuming team plans to use both the beta and production environments, you will need to create two separate app clients- one in each respective AWS account.
**Automatic Scope Generation:**
The script automatically creates these standard scopes:
- `{compact}/readGeneral` - General read access for the compact
- `{state}/{compact}.write` - Write access for the specific state/compact combination

The cognito token URL for the beta environment is `https://compact-connect-staff-beta.auth.us-east-1.amazoncognito.com/oauth2/token`
The cognito token URL for the prod environment is `https://compact-connect-staff.auth.us-east-1.amazoncognito.com/oauth2/token`


### 4. **Send Credentials to Consuming Team**
- The client_id and client_secret will be needed by the consuming team to authenticate with the API. This information is returned in the response of the cli command.
```
{
"UserPoolClient": {
"ClientId": "6g34example89j",
"ClientSecret": "1234example567890",
...
}
}
```

These credentials should be securely transmitted to the consuming team via an encrypted channel (i.e., a one-time use link) in the following format:
**When using the Python script (recommended):**
The script will output comprehensive JSON with all necessary information for the consuming team:
```json
{
"clientId": "<client id>",
"clientSecret": "<client secret>"
"clientId": "6g34example89j",
"clientSecret": "1234example567890",
"compact": "octp",
"state": "la",
"authUrl": "https://compact-connect-staff-beta.auth.us-east-1.amazoncognito.com/oauth2/token",
"licenseUploadUrl": "https://api.beta.compactconnect.org/v1/compacts/octp/jurisdictions/la/licenses"
}
```
**Important:** These credentials should be securely transmitted to the consuming team via an encrypted channel (i.e., a one-time use link). The Python script output is ready to use directly with your one-time secret link generator. Once you have sent the credentials over to the IT staff, ensure you remove all remnants of the credentials from your device.


#### Email Instructions for consuming team
As part of the email message sent to the consuming team, be sure to attach the onboarding instructions document ("Compact Connect Automated License Upload Instructions.txt").
As part of the email message sent to the consuming team, be sure to include the onboarding instructions document from the `it_staff_onboarding_instructions/` directory.

## Rotating App Client Credentials
Unfortunately, AWS Cognito does not support rotating app client credentials for an existing app client. The only way to rotate credentials is to create a new app client with a new clientId and clientSecret and then delete the old one. The following process should be performed if credentials are accidentally exposed or in the event of a security breach where the old credentials are compromised.

### 1. Pre-rotation Tasks
- Contact consuming team to schedule rotation
- Follow "Creating a New App Client" steps above, you will increment clientName version suffix by 1 (e.g. "example-ky-app-client-v1" -> "example-ky-app-client-v2")
- Update yaml file with new clientId, clientName, and createdDate
- Follow "Creating a New App Client" steps above using either the Python script (recommended) or AWS CLI, you will increment clientName version suffix by 1 (e.g. "example-ky-app-client-v1" -> "example-ky-app-client-v2")
- Update the external Google Sheet registry with new client information

### 2. Migration
- Provide new client id and client secret to consuming team
Expand Down
Loading