Intelligent API Gateway with rate limiting and anomaly detection
Project description
SentinelAPI
SentinelAPI is an intelligent API gateway that provides JWT auth, per-user rate limiting, structured request telemetry, and scheduled anomaly detection with auto-blocking.
Quick showcase:
sample-usage.md(short examples for portfolio/demo readers)
Why no Amazon Lookout for Metrics?
We intentionally do not implement Lookout for Metrics because it is not practical for free-tier testing in this project. Instead, anomaly detection is implemented with a scheduled Lambda on DynamoDB aggregates, with SNS alerting and optional auto-blocking.
Architecture
SentinelAPI uses one cloud-native architecture:
- ECS Fargate service behind an ALB
- ElastiCache Redis for token-bucket rate limiting
- DynamoDB for request logs, aggregates, and blocklist state
- EventBridge schedule -> Lambda anomaly detector -> SNS alerts
- Fargate tasks in public subnets, no NAT gateway
Optimization Presets
SentinelAPI supports optional optimization presets in code:
cost(default)performance
Set with:
SENTINEL_API_OPTIMIZE_FOR=cost
# or
SENTINEL_API_OPTIMIZE_FOR=performance
Preset values are defaults only. Any explicitly provided knob in shell env or .env overrides the preset.
Environment File
.env is optional. SentinelAPI SDK deploy reads:
- System environment variables
.envin repo root (if present)
Required:
SENTINEL_API_UPSTREAM_BASE_URL- at least one auth method:
SENTINEL_API_JWT_SECRET_KEY(HS*)SENTINEL_API_JWT_PUBLIC_KEY(static public key)SENTINEL_API_JWT_JWKS_URL(OIDC/JWKS)
Optional:
SENTINEL_API_OPTIMIZE_FOR- explicit knob overrides (Fargate sizing, desired count, rate/anomaly knobs, timeouts, JWT algorithm)
- optional image source overrides:
SENTINEL_API_GATEWAY_IMAGE_REPOSITORYSENTINEL_API_GATEWAY_IMAGE_TAGSENTINEL_API_BUILD_GATEWAY_IMAGE=true(force local build/push)
Precedence:
- Explicit shell/CI env vars
.env(if present)- Built-in preset defaults (
costorperformance)
One-Command AWS Deploy (SDK Full Stack)
./deploy.sh
One-Command AWS Teardown
./teardown.sh
Requirements:
- AWS credentials configured locally
- Docker installed and running only if
SENTINEL_API_BUILD_GATEWAY_IMAGE=true
Before deploy, set SENTINEL_API_UPSTREAM_BASE_URL in .env to the backend you want SentinelAPI to protect.
You can set it either in your shell/CI environment or in .env.
For the example Lambda backend, use the Function URL printed by:
./examples/example-api/bare-api/scripts/deploy.sh
JWT Configuration
SentinelAPI does not auto-generate JWT verification keys.
You must provide auth settings via shell env or .env before deploy.
At least one is required:
SENTINEL_API_JWT_SECRET_KEYfor HS* verificationSENTINEL_API_JWT_PUBLIC_KEYfor static RS*/ES* public-key verificationSENTINEL_API_JWT_JWKS_URLfor JWKS-based verification (recommended)
Local Testing and Linting
./scripts/test.sh
make lint
Makefile Shortcuts
make lint
make test
make deploy
make teardown
CI/CD (GitHub Actions + OIDC)
Workflow file: .github/workflows/deploy.yml
On push to main:
lintjob runsrufftestjob runspytestpublish_arch_diagramjob renders Mermaid diagram source (diagrams/arch-diagram.mmd) and uploads SVG tos3://<portfolio-assets-bucket>/sentinelapi/diagrams/arch-diagram.svgvalidate_templatesjob runs SDK dry-run plandeployjob calls reusable integration workflow (.github/workflows/integration-tests.yml) with per-run names, runs smoke checks, then attempts teardown of that run's stacks
Additional cleanup guardrail:
.github/workflows/cleanup-ci-stacks.ymlruns onworkflow_runcompletion (including cancelled runs) forDeploy SentinelAPIandRelease to PyPI.- It derives stack names from
workflow_run.idand tears down:SentinelCIIntegrationTest-<run_id>sentinel-example-api-ci-<run_id>
Required secret:
AWS_DEPLOY_ROLE_ARNSENTINEL_API_UPSTREAM_BASE_URLSENTINEL_API_JWT_SECRET_KEY
Required repository variable:
ASSET_BUCKET_TAG(format:key=value, example:sokech:resource-role=portfolio-assets)ENABLE_INTEGRATION_TESTS(true|false; used bydeploy.ymlon pushes tomainto enable/disable long AWS integration runs)
Release note:
release.ymlalways runs integration tests before publishing.
PyPI Release Pipeline
Workflow file: .github/workflows/release.yml
Trigger:
- push a tag like
v0.1.1 - or run workflow manually from Actions tab
Pipeline stages:
- lint + tests
- build wheel/sdist +
twine check - reusable integration tests (
.github/workflows/integration-tests.yml) - build and push multi-arch gateway image (
linux/amd64,linux/arm64) to ECR Public - publish to PyPI
Tag and push release:
git tag v0.1.1
git push origin v0.1.1
Required one-time setup:
- Create project on PyPI (name:
sentinel-api) or reserve the name. - In GitHub repo settings, add environment
pypi. - In PyPI project settings, add a trusted publisher:
- Owner:
SamioneX - Repository:
SentinelAPI - Workflow:
release.yml - Environment:
pypi
- Owner:
Runtime Backends
SentinelAPI runtime uses fixed backends:
- rate limiting: Redis
- request logging: DynamoDB
JWT Verification Modes
- Shared-secret/static-key mode:
SENTINEL_API_JWT_SECRET_KEY(HS256) orSENTINEL_API_JWT_PUBLIC_KEY
- JWKS discovery mode:
SENTINEL_API_JWT_JWKS_URLSENTINEL_API_JWT_JWKS_CACHE_TTL_SECONDS
When SENTINEL_API_JWT_JWKS_URL is set, JWKS key selection by token kid is used.
JWT Testing Quickstart
python3 scripts/generate_jwt.py --env-file .env --user-id demo-user
TOKEN="$(python3 scripts/generate_jwt.py --env-file .env --user-id demo-user)"
curl -X GET "http://localhost:8000/auth/verify" \
-H "Authorization: Bearer ${TOKEN}"
curl -X GET "http://localhost:8000/proxy/v1/orders?limit=5" \
-H "Authorization: Bearer ${TOKEN}"
Anomaly Detection Smoke Test
You can validate the anomaly pipeline end-to-end without waiting for the 15-minute schedule.
Requirements:
- Sentinel stack deployed
- example upstream reachable
- JWT secret available in env:
SMOKE_JWT_SECRET_KEY(preferred), orSENTINEL_API_JWT_SECRET_KEY
Run:
python3 scripts/anomaly_smoke.py --stack-name SentinelSdkFull --region us-east-1
What it does:
- seeds baseline traffic into aggregate buckets
- sends a burst of authenticated requests through the ALB
- invokes the anomaly Lambda directly
- checks that the user appears in the blocklist table
If needed, tune sensitivity in the command:
python3 scripts/anomaly_smoke.py \
--stack-name SentinelSdkFull \
--region us-east-1 \
--baseline-hourly 10 \
--burst-requests 120
Core Components
- API app:
src/sentinel_api/main.py - Auth:
src/sentinel_api/services/auth.py - Rate limiting:
src/sentinel_api/services/rate_limiter.py - Request logging:
src/sentinel_api/services/request_logger.py - Anomaly Lambda:
lambda/anomaly_detector/handler.py - SDK deploy library:
src/sentinel_api/sdk_deployer.py - SDK templates:
infrastructure/templates/foundation.yaml,infrastructure/templates/full.yaml
Example Backend
Use examples/example-api as an upstream target:
- deploy:
./examples/example-api/bare-api/scripts/deploy.sh - destroy:
./examples/example-api/bare-api/scripts/destroy.sh
InfraKit + SDK Strategy
SentinelAPI uses an SDK-native deploy model designed to align with InfraKit's lean approach and avoid CDK runtime dependency.
- migration docs:
infrastructure/README.md - parity tracker:
infrastructure/PARITY_CHECKLIST.md - full stack deploy:
./deploy.sh - full stack teardown:
./teardown.sh - foundation deploy:
python3 infrastructure/deploy.py --stack-name SentinelSdkFoundation --region us-east-1 - foundation teardown:
python3 infrastructure/teardown.py --stack-name SentinelSdkFoundation --region us-east-1
Importable API (for InfraKit/provider integration):
from sentinel_api import deploy_foundation, deploy_full, teardown_foundation
Adoption Docs and Templates
- Product-style onboarding:
USAGE.md - Proposed InfraKit custom resource contract:
infrakit/resource-spec.md - InfraKit templates:
infrakit/templates/sentinelapi-minimal.yamlinfrakit/templates/sentinelapi-production.yaml
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sentinel_api-1.0.7.tar.gz.
File metadata
- Download URL: sentinel_api-1.0.7.tar.gz
- Upload date:
- Size: 37.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cca445cab3d0571b8374918596f29f4600a853c13798232ae7666470fcb47fb3
|
|
| MD5 |
9e0de382bd2d419aa8acfea2606f4c63
|
|
| BLAKE2b-256 |
e43fc9263611df3d1084386e763dec91151e7dc922263376bc90d6251a6b7a54
|
Provenance
The following attestation bundles were made for sentinel_api-1.0.7.tar.gz:
Publisher:
release.yml on SamioneX/SentinelAPI
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sentinel_api-1.0.7.tar.gz -
Subject digest:
cca445cab3d0571b8374918596f29f4600a853c13798232ae7666470fcb47fb3 - Sigstore transparency entry: 1037150831
- Sigstore integration time:
-
Permalink:
SamioneX/SentinelAPI@fcf9c71035a067f6418889d9feea404662558146 -
Branch / Tag:
refs/tags/v1.0.7 - Owner: https://github.com/SamioneX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fcf9c71035a067f6418889d9feea404662558146 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sentinel_api-1.0.7-py3-none-any.whl.
File metadata
- Download URL: sentinel_api-1.0.7-py3-none-any.whl
- Upload date:
- Size: 33.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1e89a9a54a85c1e4fcf103c7e623b60554f74b40a5f0972f9370a505743c2b8
|
|
| MD5 |
92ed77bedd80814e8bac82edb95b6463
|
|
| BLAKE2b-256 |
5cb41b47b4655e7a248897ea3818db5504afd93f3cc42f9a62c618d1559d24bf
|
Provenance
The following attestation bundles were made for sentinel_api-1.0.7-py3-none-any.whl:
Publisher:
release.yml on SamioneX/SentinelAPI
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sentinel_api-1.0.7-py3-none-any.whl -
Subject digest:
e1e89a9a54a85c1e4fcf103c7e623b60554f74b40a5f0972f9370a505743c2b8 - Sigstore transparency entry: 1037150912
- Sigstore integration time:
-
Permalink:
SamioneX/SentinelAPI@fcf9c71035a067f6418889d9feea404662558146 -
Branch / Tag:
refs/tags/v1.0.7 - Owner: https://github.com/SamioneX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fcf9c71035a067f6418889d9feea404662558146 -
Trigger Event:
push
-
Statement type: