Runner
A ruby on rails app which displays the form to the end user, the runner is single tenanted, each runner is an individual form.
Runner [To be reviewed]
Runners are single-tenanted, and each runner instance hosts an individual form.
At the start of each request, the Runner must:
- Read the userID from the users’ cookie
If not present, generate a userID and store it in the cookie
- Read the userToken from the users’ cookie
If not present, generate a 256-bit random hex string and store it as userToken in the cookie
- Read the Digest from the user’s cookie
The Digest MUST equal the SHA-256 Hash of userID + userToken + serviceToken
If it does not, the runner must return HTTP status 400 (Bad Request) and cease any further processing
- Request the user data from the Datastore API
The URL will be of the form /service/(service-slug)/user/(userId).json
- The request must be signed using JWT with the service’s serviceToken (this will be injected into the Runner’s container as an environment variable called SERVICE_TOKEN, by Publisher). Suggested algorithm: HMAC with SHA-256
- Signing options should include iat: (current timestamp)to allow a time-limit and mitigate against replay attacks
The resulting token must be passed as a header called x-access-token
- If the data exists, the response will be a JSON packet of the form:
{
"timestamp": "(ISO8601-formatted datetime of last update)",
"payload": "(user data encrypted with userToken)"
}
The Runner can then decrypt the payload with the userToken and use it as required
- If the data does not exist, the response will have a 404 status and an empty body
- If the token is not present, the response will be 401 Unauthorised
- If the token is not valid, the response will be 403 Forbidden
To store data in the user data store, the Runner must:
Encrypt the JSON packet containing the data to be stored with the AES-256 algorithm, using the userToken as the key
POST the payload to /service/(service slug)/user/(userId).json
The body must be of the form:
{
"payload": "(encrypted data)"
}
The request must be signed using JWT with the service’s serviceToken (this will be injected into the Runner’s container as an environment variable called SERVICE_TOKEN, by Publisher) Signing options should include iat: (current timestamp)
to allow a time-limit and mitigate against replay attacks
The resulting token must be passed as a header called x-access-token
- If the request was successful, the response status will be 201 Created (if no matching record previously existed) or 204 No Content (if a matching record did already exist)
- If the token is not present, the response will be 401 Unauthorised
- If the token is not valid, the response will be 403 Forbidden
Acceptance tests
Acceptance tests can be found in the fb-acceptance-tests repo. All the forms that are tested against live in the formbuilder-services-test-dev
namespace.
New Runner Acceptance Tests: https://new-runner-acceptance-tests.dev.test.form.service.justice.gov.uk
Acceptance Tests Branching Fixture 10: https://acceptance-tests-branching-fixture-10.dev.test.form.service.justice.gov.uk
Full list of acceptance forms can be obtained from this env file.
We do not have any RBAC in place yet for shared permission to the forms so you will have to visit each service URL directly in the Editor:
All of the above forms are tested whenever the fb-runner is deployed. Once the containers are deployed and restarted the deployment pipline will trigger.
Any forms that test submission will submit to fb-acceptance-tests@digital.justice.gov.uk. Details of how to access this account can be found in the shared LastPass. The acceptance tests will check the contents of the submission PDF to make sure it was correctly generated.
Technology
- Ruby on Rails