diff --git a/.env.example b/.env.example index fbdd5ecd11..766aa593e0 100644 --- a/.env.example +++ b/.env.example @@ -32,6 +32,7 @@ FILE_API_KEY_NEXUS=👻 FILE_API_KEY_BARNET=👻 FILE_API_KEY_LAMBETH=👻 FILE_API_KEY_SOUTHWARK=👻 +FILE_API_KEY_EPSOM_EWELL=👻 # Editor EDITOR_URL_EXT=http://localhost:3000 diff --git a/api.planx.uk/.env.test.example b/api.planx.uk/.env.test.example index ec234e54f9..4df97c1b50 100644 --- a/api.planx.uk/.env.test.example +++ b/api.planx.uk/.env.test.example @@ -22,6 +22,7 @@ FILE_API_KEY_NEXUS=👻 FILE_API_KEY_BARNET=👻 FILE_API_KEY_LAMBETH=👻 FILE_API_KEY_SOUTHWARK=👻 +FILE_API_KEY_EPSOM_EWELL=👻 # Editor EDITOR_URL_EXT=example.com diff --git a/api.planx.uk/modules/auth/middleware.ts b/api.planx.uk/modules/auth/middleware.ts index 9bd5d63ea7..d831e9a557 100644 --- a/api.planx.uk/modules/auth/middleware.ts +++ b/api.planx.uk/modules/auth/middleware.ts @@ -98,6 +98,10 @@ export const useFilePermission: RequestHandler = (req, _res, next): void => { isEqual( req.headers["api-key"] as string, process.env.FILE_API_KEY_SOUTHWARK!, + ) || + isEqual( + req.headers["api-key"] as string, + process.env.FILE_API_KEY_EPSOM_EWELL!, ); if (!isAuthenticated) return next({ status: 401, message: "Unauthorised" }); return next(); diff --git a/doc/how-to/aws/how-to-setup-aws-s3-submissions.md b/doc/how-to/aws/how-to-setup-aws-s3-submissions.md index 998f963a72..43c2949824 100644 --- a/doc/how-to/aws/how-to-setup-aws-s3-submissions.md +++ b/doc/how-to/aws/how-to-setup-aws-s3-submissions.md @@ -12,7 +12,7 @@ Once a council has confirmed they're cleared from their IT dept to use this meth 2. Create 2x tokens for sending secure requests to the Power Automate webhook and add both encrypted values to: - `team_integrations.production_power_automate_api_key` & `team_integrations.staging_power_automate_api_key` via the production Hasura console - - See `how-to-generate-a-secret` for how to properly generate tokens and encrypt values + - See `how-to-generate-a-secret` and `how-to-add-a-team-secret` for how to properly generate tokens and encrypt values 3. Create 2x tokens for downloading files from the PlanX S3 Bucket and add values to: - Root `.env.example` & `.env`, API's `.env.test` & `.env.test.example` as `FILE_API_KEY_{TEAM_SLUG}` @@ -20,7 +20,9 @@ Once a council has confirmed they're cleared from their IT dept to use this meth - Root `docker-compose.yml` - API's `modules/auth/middleware.ts` function `isAuthenticated` - Pulumi's `infrastructure/application/index.ts` list of `apiService` "environment" variables - - Run `pulumi config set file-api-key-{team_slug} --stack {stack}` 2x for each staging & production stacks - - Encrypt the values using _our_ encrypt scripts (again see `how-to-generate-a-secret`) and add to `team_integrations.production_file_api_key` & `team_integrations.staging_file_api_key` via the production Hasura console. Please note these values are _not_ currently read, but suitable for a potential future refactor (just a bit tricky because file API keys are issued to a mix of _teams_ and _systems_ (eg BOPS & Idox)). + - Run `pulumi config set file-api-key-{team_slug} {your-new-secret} --secret --stack {stack}` once for each staging & production stacks, making sure that the secret you used for the root `.env` is the STAGING secret. + - Encrypt the values using _our_ encrypt scripts (see [`how-to-add-a-team-secret.md`](https://github.com/theopensystemslab/planx-new/blob/main/doc/how-to/secrets/how-to-add-a-team-secret.md)) and add to `team_integrations.production_file_api_key` & `team_integrations.staging_file_api_key` via the production Hasura console. Please note these values are _not_ currently read, but suitable for a potential future refactor (just a bit tricky because file API keys are issued to a mix of _teams_ and _systems_ (eg BOPS & Idox)). -4. Securely share tokens back to council contact via onetimesecret or similar +4. Securely share all four raw tokens back to council contact via onetimesecret or similar: +- The two Power Automate API keys +- The two file API keys diff --git a/doc/how-to/secrets/how-to-add-a-team-secret.md b/doc/how-to/secrets/how-to-add-a-team-secret.md index dfed00ba3f..ab1b13555a 100644 --- a/doc/how-to/secrets/how-to-add-a-team-secret.md +++ b/doc/how-to/secrets/how-to-add-a-team-secret.md @@ -17,6 +17,7 @@ This guide will demonstrate how to - > [!NOTE] > The `stack_name` should be either `production` or `staging`, depending on which environment the secret is for (e.g. `staging_govpay_secret`). +> I.e. the staging encryption key needs to be used for staging secrets (even though they need to get set on the production database) ### Encrypt the secret 1. In `/scripts/encrypt`, run the encryption script using the encryption key and raw secret that you obtained in the previous steps: `pnpm encrypt `. diff --git a/doc/how-to/secrets/how-to-generate-a-secret.md b/doc/how-to/secrets/how-to-generate-a-secret.md index afe1abea4a..01839a36f3 100644 --- a/doc/how-to/secrets/how-to-generate-a-secret.md +++ b/doc/how-to/secrets/how-to-generate-a-secret.md @@ -5,7 +5,7 @@ 2. Secrets must meet the following criteria - * Have a minimum length of 32 characters * All characters should be alphanumeric -3. Follow [the current process for adding secrets](https://github.com/theopensystemslab/planx-new/blob/main/doc/how-to/how-to-add-a-secret.md) to the application +3. Follow [the current process for adding secrets](https://github.com/theopensystemslab/planx-new/blob/main/doc/how-to/secrets/how-to-add-a-secret.md) to the application ## Principles - Staging and Production environments should not share secrets diff --git a/docker-compose.yml b/docker-compose.yml index e846bfee9d..34a4c69e8d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -127,6 +127,7 @@ services: FILE_API_KEY_BARNET: ${FILE_API_KEY_BARNET} FILE_API_KEY_LAMBETH: ${FILE_API_KEY_LAMBETH} FILE_API_KEY_SOUTHWARK: ${FILE_API_KEY_SOUTHWARK} + FILE_API_KEY_EPSOM_EWELL: ${FILE_API_KEY_EPSOM_EWELL} FILE_API_KEY_NEXUS: ${FILE_API_KEY_NEXUS} FILE_API_KEY: ${FILE_API_KEY} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} diff --git a/infrastructure/application/Pulumi.production.yaml b/infrastructure/application/Pulumi.production.yaml index ba75a36fc7..1abd12ce1e 100644 --- a/infrastructure/application/Pulumi.production.yaml +++ b/infrastructure/application/Pulumi.production.yaml @@ -10,6 +10,8 @@ config: secure: AAABAGyTfLujGho+V0tEhFXQRET5FjYK6txyaFTB3gY/VaKzq8yNlocJTAM5nt8mBhF6T+AeQD2GxW63 application:file-api-key-barnet: secure: AAABANMl+fVFsRVGXvJV/aLManXO+TldXVDhp5QH6KGWJoG7O9Ket63zIW1iOiinINWJ2I5OizI= + application:file-api-key-epsom-ewell: + secure: AAABANvwhiVRBq8NH7ZqcToUzYn4X+KfC5Wm8WjWUKXT5TuVXqC6zHhVVKFBbmdtKjC4j5M4+bWsLiFO9dO0MLobxLpK7YCE application:file-api-key-lambeth: secure: AAABAMNhdCTlFx3fZH/nO71ildypZB2JR5NixlQCENsS1VqwdiOX17q/Gi1UFrCQi2qaY2sZFG4= application:file-api-key-nexus: diff --git a/infrastructure/application/Pulumi.staging.yaml b/infrastructure/application/Pulumi.staging.yaml index be082e9ca8..5c34389e81 100644 --- a/infrastructure/application/Pulumi.staging.yaml +++ b/infrastructure/application/Pulumi.staging.yaml @@ -11,6 +11,8 @@ config: secure: AAABAN0LjLOgxCkr5ZqQLn6FkZPcrPlvNG4fbNZ02W2qC1VVYVee/3aToZQuXuokVwnIPNbbe2w= application:file-api-key-barnet: secure: AAABAFpZq81zy3CKFXUgi9oEGIGp7LDVD3TNlYkZD4liX0bxOrmMJYdDpMmyGt4aGARF63nEUmo= + application:file-api-key-epsom-ewell: + secure: AAABAD1/nlJ2EOEglLiiNsOLbOd3KWCONhNhJAIdZQVnrSRsNIzX2luszOreQf20EYl8AZ4L1TiheqUHSt22e5z1FiLWoCtY application:file-api-key-lambeth: secure: AAABALQTeIf/uScxASJkhmoPRhewQT94Guad4iJ7GRk0DcND8wDUG0eNxDU4+XwUQZqCnL2DP+E= application:file-api-key-nexus: @@ -36,6 +38,8 @@ config: secure: AAABACbmLC4176IBxX5iL64/nycSXEsCYSQ0hTb7t2OCVlWUc627Vr/EpBhcqPrw9q+0z8UOvRJG5/c/DflZxfPxyJRUVNu+ application:mapbox-access-token: secure: AAABAMWf2zVq5/mKCLynpgzAidNsnbUEBpb47n7MRWp2xzRgwaf3kzOvnZax9N04ZScQqU6I5/tEKTBAbSb8MIBJ8mU2iTZbPg8FD6wYsetRyftm1K39KBsIl9aS7fXvZFOG7BsC4qMDEhlDkH8gbV2HTev3VvvRUe3lzVhjNGNHqQ== + application:metabase-api-key: + secure: AAABAFf+hW09AWupsY6adrPAJHCkrTMeRX7/gaUHLYXi3QS77MVelPp9K0L4zyUL8u7zDanjuE9G/bfIlcVXLwiLLKAJkt5to9knKJqTXg== application:metabase-encryption-secret-key: secure: AAABAGmfVICD8sR+IE6mHC8BNUY1WQXGCbv5F3C1fSgA+1ADiRem3GNrwY0YRZociRYuPIo3MIRS0aIg44jt10SBCE0ik58wHamcKA== application:metabasePgPassword: @@ -66,5 +70,3 @@ config: certificates:cloudflare-zone-id: dc27ac531ff8862559ed9ab5016c4953 cloudflare:apiToken: secure: AAABABWhDm+7RstbxLXd1D8CcxkylHS6UKMqk4kOaY7Y0E7FJS4bZfvyGs0nks80hl3vjENH4eDuFbUgA82/sA4SmDlfpNXr - application:metabase-api-key: - secure: AAABAFf+hW09AWupsY6adrPAJHCkrTMeRX7/gaUHLYXi3QS77MVelPp9K0L4zyUL8u7zDanjuE9G/bfIlcVXLwiLLKAJkt5to9knKJqTXg== diff --git a/infrastructure/application/index.ts b/infrastructure/application/index.ts index c0cd37a8a4..96cd773299 100644 --- a/infrastructure/application/index.ts +++ b/infrastructure/application/index.ts @@ -359,6 +359,10 @@ export = async () => { name: "FILE_API_KEY_SOUTHWARK", value: config.requireSecret("file-api-key-southwark"), }, + { + name: "FILE_API_KEY_EPSOM_EWELL", + value: config.requireSecret("file-api-key-epsom-ewell"), + }, { name: "GOOGLE_CLIENT_ID", value: config.require("google-client-id"),