SECA-compatible proxy for Hetzner Cloud.
Current focus is practical conformance plus real provider behavior for core resources, including an opt-in internet-gateway implementation backed by a managed NAT VM.
make bootstrap
make fmt
make test
make buildRun locally:
SECA_DATABASE_URL='postgres://postgres:postgres@localhost:5432/secapi_proxy?sslmode=disable' \
SECA_PUBLIC_BASE_URL='http://localhost:8080' \
SECA_ADMIN_LISTEN_ADDR='127.0.0.1:8081' \
SECA_ADMIN_TOKEN='dev-admin-token' \
SECA_CREDENTIALS_KEY='MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=' \
make runHealth:
GET /healthzGET /readyzGET /.wellknown/secapi
docker compose up --buildUseful checks:
curl -s http://localhost:8080/healthz | jq
curl -s http://localhost:8080/v1/regions | jq
curl -s http://localhost:8080/compute/v1/tenants/dev/skus | jq
curl -s http://localhost:8080/storage/v1/tenants/dev/images | jq- No global Hetzner token is used for runtime resource operations.
- Tokens are workspace-scoped and persisted via admin binding.
SECA_ADMIN_TOKENsecures/admin/v1/...endpoints.SECA_CREDENTIALS_KEYis required for at-rest credential encryption.
Use token-provisioner so newly created workspaces in creating become usable:
export SECA_TOKEN_PROVISIONER_HETZNER_TOKEN='<token-from-hetzner-console>'
export SECA_ADMIN_TOKEN='dev-admin-token'
export SECA_PUBLIC_BASE_URL='http://localhost:8080'
export SECA_ADMIN_BASE_URL='http://127.0.0.1:8081'
export SECA_TENANTS='dev'
./scripts/token-provisioner.shOptional:
SECA_TOKEN_PROVISIONER_INTERVAL(default1)HCLOUD_ENDPOINTHCLOUD_PROJECT_REF
SECA_ADMIN_TOKENSECA_CREDENTIALS_KEYSECA_LISTEN_ADDR(default:8080)SECA_ADMIN_LISTEN_ADDR(default127.0.0.1:8081)SECA_PUBLIC_BASE_URL(defaulthttp://localhost:8080)SECA_DATABASE_URLSECA_CONFORMANCE_MODE(bool)SECA_HETZNER_AVAILABILITY_CACHE_TTL(default60s; set0sto disable cache)SECA_INTERNET_GATEWAY_NAT_VM(defaultfalse)HCLOUD_ENDPOINTHCLOUD_HETZNER_ENDPOINT
Enable:
export SECA_INTERNET_GATEWAY_NAT_VM=trueBehavior when enabled:
- creates one managed Hetzner VM per SECA internet-gateway
- applies cloud-init to enable IPv4 forwarding + SNAT rules
- syncs network attachments from route-table usage
- programs Hetzner network routes (
destination -> IGW private IP) - removes managed VM when no route-table references remain
Notes:
- this is a provider polyfill (Hetzner has no native internet-gateway resource)
- for private-only workload instances, guest default route/DNS behavior may still require explicit handling depending on image/network stack
./examples/internet-gateway-e2e.shThis script creates:
- workspace
- network
- internet-gateway
- route-table default route to internet-gateway
Then prints resulting resources for inspection.
Official runner:
https://github.com/eu-sovereign-cloud/conformance
Targets:
make conformance-smoke
make conformance-region
make conformance-auth
make conformance-workspace
make conformance-compute
make conformance-storage
make conformance-network
make conformance-foundation
make conformance-foundation-core
make conformance-fullExample override:
make conformance-smoke \
CONFORMANCE_PROVIDER_REGION_V1='http://localhost:8080' \
CONFORMANCE_PROVIDER_AUTHORIZATION_V1='http://localhost:8080' \
CONFORMANCE_CLIENT_AUTH_TOKEN='dev-token' \
CONFORMANCE_CLIENT_TENANT='dev' \
CONFORMANCE_CLIENT_REGION='fsn1'Results path:
.artifacts/conformance/results
make ci-verifymake ci-unitmake ci-integrationmake ci-contractmake ci-packagemake migrate-upmake migrate-downmake sqlc-gen