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

chore: Add decrypt to build site params #465

Merged
merged 1 commit into from
May 15, 2024
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
5 changes: 3 additions & 2 deletions .cloudgov/manifest.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
---
applications:
- name: ((product))-build-container((env_postfix))
no-route: true
Expand All @@ -7,6 +7,7 @@ applications:
services:
- federalist-((env))-rds
- federalist-((env))-uev-key
- pages-((env))-encryption
metadata:
labels:
type: build-container
Expand All @@ -25,4 +26,4 @@ applications:
type: build-container
name: exp
annotations:
command: cd app && ./build -p
command: cd app && ./build -p
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ One of the following flags *must* be specified:

| Flag | Example | Description |
| ---- | ------- | ----------- |
| `-p`, `--params` | `-p '{"foo": "bar"}'` | A JSON encoded string containing the [build arguments](#build-arguments) |
| `-p`, `--params` | `-p '{"foo": "bar"}'` | An encrypted JSON encoded string containing the [build arguments](#build-arguments) |
| `-f`, `--file` | `--file ./.local/my-build.json` | A path to a JSON file containing the [build arguments](#build-arguments) |

### Using cloud.gov tasks
Expand Down Expand Up @@ -53,6 +53,14 @@ docker-compose run --rm app python main.py -f /tmp/local/my-build.json

When running locally, environment variables are configured in `docker-compose.yml` under the `app` service.

## Connected CF service

| Name | Type | Description |
| ---- | ---- | ----------- |
| `federalist-((env))-rds` | Brokered | The RDS db credentials |
| `federalist-((env))-uev-key` | User Provided | The site environment variable encryption key |
| `pages-((env))-encryption` | User Provided | The site build params encryption key |

## Build arguments

| Name | Optional? | Default | Description |
Expand All @@ -73,6 +81,10 @@ When running locally, environment variables are configured in `docker-compose.ym
| `user_environment_variables` | Y | | Array of objects containing the name and encrypted values of user-provided environment variables (Ex. `[{ name: "MY ENV VAR", ciphertext: "ABC123" }]`) |


### Encrypted params argument

When build parameters are passed to the build script using the `-p / --params` flag, they are an encrypted JSON encoded string created by the pages-core queue worker and decrypted using a shared key stored as CF user provided service `pages-<env>-encryption` and the [decrypt cipher](./src/crypto/decrypt.py).

## Environment variables provided during builds

The following environment variables are available during site builds and when running the `federalist` npm script. They may be useful for customizing the display of certain information in the published site, for example, to display the current published branch name.
Expand Down
20 changes: 19 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import shlex

from build import build
from crypto.decrypt import decrypt


def load_vcap():
Expand All @@ -24,6 +25,22 @@ def load_vcap():
os.environ[uev_env_var] = uev_ups['credentials']['key']


def decrypt_params(encrypted):
vcap_application = json.loads(os.getenv('VCAP_APPLICATION', '{}'))
vcap_services = json.loads(os.getenv('VCAP_SERVICES', '{}'))

space = vcap_application['space_name']

encryption_ups = next(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a realistic possibility that a matching service might not be found?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. We couple the service with the deployment and there would be a deploy error if the service didn't connect.

ups for ups in vcap_services['user-provided']
if ups['name'] == f'pages-{space}-encryption'
)

encryption_key = encryption_ups['credentials']['key']

return decrypt(args.params, encryption_key)


if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Run a pages build')
group = parser.add_mutually_exclusive_group(required=True)
Expand All @@ -36,7 +53,8 @@ def load_vcap():
args = parser.parse_args()

if args.params:
params = json.loads(args.params)
decrypted = decrypt_params(args.params)
params = json.loads(decrypted)
else:
params = json.load(args.file)

Expand Down
Loading