Skip to content

Commit 67cb5fa

Browse files
initial readme
1 parent b60d8eb commit 67cb5fa

1 file changed

Lines changed: 1 addition & 155 deletions

File tree

README.md

Lines changed: 1 addition & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1 @@
1-
# Sample API
2-
3-
A minimal HTTP API and custom authorizer designed to run as AWS Lambda functions behind API Gateway.
4-
It includes a mock API with scope-based access control, a token authorizer, and an optional mTLS proxy for testing secure client authentication.
5-
6-
---
7-
8-
## Overview
9-
10-
### Components
11-
- **Authorizer**: validates OAuth2 tokens and supports mTLS-based client certificate checks.
12-
- **Mock API**: exposes simple domain endpoints (`customer`, `energy`) with scope enforcement.
13-
- **mTLS Proxy**: optional TLS termination layer for local or secure deployments.
14-
- **LocalStack setup script**: provisions IAM roles, Lambdas, and API Gateway locally for testing.
15-
16-
---
17-
18-
## Mutual TLS (mTLS) Server
19-
20-
Located in `/cmd/mtls`, this service:
21-
- Terminates TLS and enforces client certificate authentication.
22-
- Validates certificates against a trusted CA bundle.
23-
- Uses server and client keys stored in SSM (simulated via LocalStack).
24-
25-
---
26-
27-
## Features
28-
29-
- AWS Lambda–compatible handlers using `aws-lambda-go-api-proxy`.
30-
- Example endpoints:
31-
- `GET /customer/v1/customer` → requires scope: `customer`
32-
- `GET /energy/v1/energy` → requires scope: `energy`
33-
- `GET /health` → liveness check
34-
- Scope-based authorization via:
35-
- Lambda authorizer context (when deployed)
36-
- Bearer token fallback (for local use)
37-
- `x-fapi-interaction-id` header validation (must be UUIDv4).
38-
39-
---
40-
41-
## Requirements
42-
43-
- Go 1.24+
44-
- Docker
45-
- LocalStack (for local AWS simulation)
46-
- Optional AWS account for live testing
47-
48-
---
49-
50-
## Environment Variables
51-
52-
| Variable | Description |
53-
|-----------|-------------|
54-
| `AWS_LOCAL` | Set to `true` when running under LocalStack |
55-
| `REGION` | AWS region (default `us-east-1`) |
56-
| `CLIENT_CERT_HEADER` | Header name for mTLS client cert (e.g. `TLS-Certificate`) |
57-
| `INTROSPECTION_ENDPOINT` | Token introspection URL *(leave blank locally)* |
58-
| `USER_INFO_ENDPOINT` | User info URL *(leave blank locally)* |
59-
| `CLIENT_ID` | OAuth2 client ID *(leave blank locally)* |
60-
| `SSM_TRANSPORT_CERTIFICATE_NAME` | SSM name for server certificate |
61-
| `SSM_TRANSPORT_KEY_NAME` | SSM name for server private key |
62-
| `SSM_CA_TRUSTED_LIST_NAME` | SSM name for CA certificates |
63-
64-
When using LocalStack, TLS materials are automatically uploaded to SSM under `/sample-api/...`.
65-
66-
---
67-
68-
## Running locally
69-
Option A: Go build/run
70-
- This Lambda-oriented service is designed for API Gateway/Lambda. For local invocation you typically run with a Lambda runtime emulator (e.g., aws-lambda-rie) or SAM CLI.
71-
72-
Example with AWS SAM (simplified outline):
73-
- Create a SAM template wiring API Gateway → Lambda (runtime: provided.al2, image-based or binary handler).
74-
- Set env vars (AWS_LOCAL, REGION).
75-
- Run: sam local start-api
76-
77-
Option B: Docker container
78-
- The provided Dockerfile builds a minimal image suitable for local or image-based Lambda deployment.
79-
80-
Build:
81-
- docker build -t mockapi:local .
82-
83-
Run against LocalStack:
84-
- docker network create localstack || true
85-
- docker run --rm -p 443:443
86-
--network localstack
87-
-e AWS_LOCAL=true
88-
-e REGION=eu-west-1
89-
--name mockapi
90-
mockapi:local
91-
92-
Notes:
93-
- The container exposes port 443.
94-
- Ensure LocalStack is reachable on the same Docker network as localstack.local:4566.
95-
96-
## Authorization and scopes
97-
Each protected endpoint requires specific scopes:
98-
- /sample/protected → sample
99-
100-
How scopes are resolved:
101-
1. When behind API Gateway, the handler reads them from the custom authorizer context (scope as a space-delimited string).
102-
2. Otherwise, it falls back to parsing the Authorization: Bearer token.
103-
104-
Accepted token formats for local/dev:
105-
- JWT with a space-delimited scope claim in payload.
106-
- A JSON string token that includes one of:
107-
- scope: "s1 s2"
108-
- scopes: ["s1","s2"]
109-
- permissions: ["s1","s2"]
110-
111-
Examples:
112-
- JWT payload idea (pseudo): { "sub":"123", "scope":"sample" }
113-
- JSON-string token example for sample: {"active":true,"scopes":["sample"]}
114-
115-
In practice, set an Authorization header like:
116-
- Authorization: Bearer {"active":true,"scopes":["sample"]}
117-
118-
Responses on failure:
119-
- 401 if Authorization is missing/invalid or introspection-style JSON cannot be parsed
120-
- 403 if token is valid but lacks required scopes
121-
122-
## x-fapi-interaction-id
123-
- If the client sets x-fapi-interaction-id, it must be a valid UUIDv4; otherwise the request is rejected with 400.
124-
- If missing, the server generates a UUIDv4 and echoes it in the response header.
125-
126-
## Data persistence
127-
- This sample is **stateless**. DynamoDB tables and seed data from the original demo were removed.
128-
129-
## Example requests (local)
130-
Protected endpoint (requires `sample` scope):
131-
- curl -i https://localhost:443/sample/protected \
132-
-H 'x-fapi-interaction-id: 3fa85f64-5717-4562-b3fc-2c963f66afa6' \
133-
-H 'Authorization: Bearer {"active":true,"scopes":["sample"]}'
134-
135-
Missing or invalid x-fapi-interaction-id:
136-
- If you pass x-fapi-interaction-id with an invalid format, you will get 400.
137-
- If you omit it, the response will include a generated x-fapi-interaction-id.
138-
139-
## Deployment
140-
Container image (typical for Lambda):
141-
- Build and push the image to ECR.
142-
- Create/update a Lambda function using the container image.
143-
- Configure an API Gateway HTTP API or REST API to route to the Lambda.
144-
- Configure a custom authorizer (if applicable) to provide the scope field in the authorizer context.
145-
- Set env vars (REGION, POPULATE_DB as needed; do not set AWS_LOCAL in production).
146-
147-
IAM and permissions:
148-
- The Lambda role must allow access to DynamoDB (read/write as needed for your tables).
149-
150-
## Troubleshooting
151-
- 401 Unauthorized: Missing Authorization header, malformed token, or token content cannot be parsed for scopes.
152-
- 403 Forbidden: Token valid but does not include required scope.
153-
- 400 Bad Request: x-fapi-interaction-id provided but not a valid UUIDv4.
154-
- 404 Not Found: No matching data in DynamoDB (ensure POPULATE_DB or seed data).
155-
- DynamoDB local connection issues: Verify Docker network and that LocalStack is reachable at [http://localstack.local:4566](http://localstack.local:4566) with AWS_LOCAL=true.
1+
# reference_api_resources

0 commit comments

Comments
 (0)