Skip to content

Commit a92e964

Browse files
feat: add AWS lambda for https signatures (#1964)
* feat: update local http signatures * feat: add http signature AWS lambda * chore: use env variables * feat: use lambda in pre-request scripts * fix: format * chore: use environment variables in postman * Revert "chore: use environment variables in postman" This reverts commit db00b06. * chore(postman): replace collection variables with environment variables * fix: payment pointer queries * fix: remove deprecated context.succeed * feat: move to just using one pre-request signature script * feat: move to just one pre-request signature script * docs: add POST example * feat: update signature pre request script and add one for host headers * feat: make OP example work with local and remote environment * fix: formatting * chore: remove signature service from docker compose * chore: move postman scripts and remove local signature server * feat: add postman environments * chore: remove references to local-http-signatures
1 parent 1feeba6 commit a92e964

26 files changed

+1399
-1471
lines changed

Diff for: .github/workflows/lint_test_build.yml

-10
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,6 @@ jobs:
8585
- uses: ./.github/workflows/rafiki/env-setup
8686
- run: pnpm --filter mock-account-servicing-entity build
8787

88-
local-http-signatures:
89-
runs-on: ubuntu-22.04
90-
needs: checkout
91-
timeout-minutes: 5
92-
steps:
93-
- uses: actions/checkout@v4
94-
- uses: ./.github/workflows/rafiki/env-setup
95-
- run: pnpm --filter local-http-signatures build
96-
9788
token-introspection:
9889
runs-on: ubuntu-22.04
9990
needs: checkout
@@ -117,7 +108,6 @@ jobs:
117108
- frontend
118109
- auth
119110
- mock-account-servicing-entity
120-
- local-http-signatures
121111
- token-introspection
122112
steps:
123113
- uses: actions/checkout@v4

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ build
5050
# Docusaurus
5151
.docusaurus
5252
.cache-loader
53+
54+
# AWS Lambda
55+
*.zip

Diff for: .postman/api_84fc90ca-3153-4865-8b49-b91218e5d574

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ files[] = {"id":"23674746-92761441-6d0c-4fc6-aa04-73eccf6afd4c","path":"Interled
1717
rootDirectory = postman/schemas
1818

1919
[config.relations.apiDefinition.metaData]
20+
type = openapi:3

Diff for: aws/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Workers
2+
3+
This directory contains AWS Lambdas which power some server-side functionality for Rafiki or the Open Payments APIs.
4+
5+
## Sub-projects
6+
7+
- `http-signatures` - powers the generation of request signature headers for Open Payments API requests

Diff for: aws/lambdas/http-signatures/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# HTTP Signatures AWS Lambda
2+
3+
## Installation
4+
5+
1. Navigate to this directory
6+
7+
```sh
8+
$ cd /PATH/TO/RAFIKI/aws/lambdas/http-signatures
9+
```
10+
11+
2. Install the packages using npm
12+
13+
```sh
14+
$ npm install
15+
```
16+
17+
3. Zip the lambda
18+
19+
```sh
20+
$ zip -r ../http-signatures.zip *
21+
```
22+
23+
4. Upload zipped lambda function to AWS Lambdas via the AWS console
24+
25+
## Usage
26+
27+
```sh
28+
$ curl -v 'https://<ID>.lambda-url.<REGION>.on.aws/' \
29+
-H 'content-type: application/json' \
30+
-d '{ "keyId": "<KEY_ID>", "base64Key": "<BASE64_ENCODED_Ed25519_PRIVATE_KEY>", "request":{"headers":{"host": "happy-life-bank-backend"}, "method": "GET", "url":"https://example.com"} }'
31+
```
32+
33+
or
34+
35+
```sh
36+
curl -v 'https://<ID>.lambda-url.<REGION>.on.aws/' \
37+
-H 'content-type: application/json' \
38+
-d '{ "keyId": "<KEY_ID>", "base64Key": "<BASE64_ENCODED_Ed25519_PRIVATE_KEY>", "request":{"headers":{"host": "happy-life-bank-backend"}, "method": "POST", "url":"https://example.com", "body": "{\"hello\": \"world\"}"}}'
39+
```

Diff for: aws/lambdas/http-signatures/index.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { loadBase64Key, createHeaders } from '@interledger/http-signature-utils'
2+
3+
const validateBody = (requestBody) =>
4+
!!requestBody.keyId &&
5+
!!requestBody.base64Key &&
6+
!!requestBody.request.headers &&
7+
!!requestBody.request.method &&
8+
!!requestBody.request.url
9+
10+
export const handler = async function (event) {
11+
const requestBody = JSON.parse(event.body)
12+
13+
if (!validateBody(requestBody)) {
14+
return {
15+
statusCode: '400',
16+
body: 'Unsufficient data in request body'
17+
}
18+
}
19+
20+
const { base64Key, keyId, request } = requestBody
21+
22+
let privateKey
23+
24+
try {
25+
privateKey = loadBase64Key(base64Key)
26+
} catch {
27+
return {
28+
statusCode: '400',
29+
body: 'Not a valid private key'
30+
}
31+
}
32+
33+
if (privateKey === undefined) {
34+
return {
35+
statusCode: '400',
36+
body: 'Not an Ed25519 private key'
37+
}
38+
}
39+
40+
const headers = await createHeaders({
41+
request,
42+
privateKey,
43+
keyId
44+
})
45+
delete headers['Content-Length']
46+
delete headers['Content-Type']
47+
48+
return {
49+
statusCode: '200',
50+
body: JSON.stringify(headers),
51+
headers: {
52+
'Content-Type': 'application/json'
53+
}
54+
}
55+
}

Diff for: aws/lambdas/http-signatures/package-lock.json

+62
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: aws/lambdas/http-signatures/package.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "http-signatures-lambda",
3+
"main": "index.js",
4+
"type": "module",
5+
"dependencies": {
6+
"@interledger/http-signature-utils": "1.1.0"
7+
}
8+
}

Diff for: localenv/README.md

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ These packages include:
88
- `auth` (GNAP auth server)
99
- `mock-account-servicing-entity` (mocks an [Account Servicing Entity](https://rafiki.dev/concepts/account-servicing-entity/)
1010
- `frontend` (Remix app to expose a UI for Rafiki Admin management via interaction with the `backend` Admin APIs)
11-
- `local-http-signatures` (request signature generation for Postman)
1211

1312
These packages depend on the following databases:
1413

Diff for: localenv/cloud-nine-wallet/docker-compose.yml

-15
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,6 @@ services:
7575
AUTH_DATABASE_URL: postgresql://cloud_nine_wallet_auth:cloud_nine_wallet_auth@shared-database/cloud_nine_wallet_auth
7676
depends_on:
7777
- shared-database
78-
cloud-nine-signatures:
79-
hostname: cloud-nine-wallet-signatures
80-
image: rafiki-postman-signatures
81-
build:
82-
context: ../..
83-
dockerfile: ./localenv/local-http-signatures/Dockerfile
84-
restart: always
85-
ports:
86-
- '3040:3000'
87-
environment:
88-
KEY_FILE: /workspace/private-key.pem
89-
volumes:
90-
- ../cloud-nine-wallet/private-key.pem:/workspace/private-key.pem
91-
networks:
92-
- rafiki
9378
shared-database:
9479
image: 'postgres:15' # use latest official postgres version
9580
restart: unless-stopped

Diff for: localenv/happy-life-bank/docker-compose.yml

-13
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,6 @@ services:
7070
AUTH_SERVER_DOMAIN: "http://localhost:4006"
7171
depends_on:
7272
- cloud-nine-auth
73-
happy-life-signatures:
74-
hostname: happy-life-bank-signatures
75-
image: rafiki-postman-signatures
76-
pull_policy: never
77-
restart: always
78-
ports:
79-
- '3041:3000'
80-
environment:
81-
KEY_FILE: /workspace/private-key.pem
82-
volumes:
83-
- ../happy-life-bank/private-key.pem:/workspace/private-key.pem
84-
depends_on:
85-
- cloud-nine-signatures
8673
happy-life-admin:
8774
hostname: happy-life-bank-admin
8875
image: rafiki-frontend

Diff for: localenv/local-http-signatures/Dockerfile

-58
This file was deleted.

Diff for: localenv/local-http-signatures/README.md

-34
This file was deleted.

Diff for: localenv/local-http-signatures/package.json

-28
This file was deleted.

0 commit comments

Comments
 (0)