No description
  • Go 91.8%
  • Shell 8.2%
Find a file
Arne Skaar Fismen 07fece31d3 fix: remove config_src from CreateTunnel request body
config_src: "cloudflare" causes Cloudflare to manage ingress remotely
and ignore the local config.yml, resulting in immediate connection
cancellation. Omitting it defaults to local config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 13:53:56 +01:00
docs/superpowers docs: add tunnel creation implementation plan 2026-03-28 12:52:38 +01:00
internal fix: remove config_src from CreateTunnel request body 2026-03-28 13:53:56 +01:00
.gitignore chore: ignore .worktrees/ 2026-03-28 12:58:08 +01:00
.golangci.yml feat: initialise module code.bas.es/bases/dev 2026-03-28 09:06:58 +01:00
deploy.sh docs: warn about CF_ACCOUNT_ID on --update for existing deployments 2026-03-28 13:36:13 +01:00
go.mod feat: initialise module code.bas.es/bases/dev 2026-03-28 09:06:58 +01:00
go.sum feat: initialise module code.bas.es/bases/dev 2026-03-28 09:06:58 +01:00
main.go feat: add CF_ACCOUNT_ID flag and wire into cf.Client 2026-03-28 13:36:13 +01:00
README.md docs: add CF_ACCOUNT_ID, document POST /tunnels, update token scope 2026-03-28 13:36:13 +01:00

dev.bas.es

DNS provisioning API for *.dev.bas.es. Runs on fismen.no, reachable at https://dev.bas.es.

Provisioning scripts call this instead of Cloudflare directly, keeping Cloudflare credentials off developer machines.

What it does

  • POST /tunnels — creates a Cloudflare tunnel and two proxied CNAMEs in one call; returns tunnel credentials
  • POST /records — creates two proxied CNAMEs for a caller-supplied tunnel ID:
    • <basename>.dev.bas.es
    • *.<basename>.dev.bas.es
  • PATCH /records/{basename} — resets the 30-day expiry
  • Records and tunnels auto-delete after 30 days (background hourly cleanup)

All endpoints require Authorization: Bearer <token>.

Usage

# Create a tunnel and DNS records in one call (recommended)
curl -X POST https://dev.bas.es/tunnels \
  -H "Authorization: Bearer $BASES_DEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"basename":"myinstance"}'
# → {"tunnel_id":"...","tunnel_secret":"...","account_tag":"..."}

# Provision DNS for an existing tunnel
curl -X POST https://dev.bas.es/records \
  -H "Authorization: Bearer $BASES_DEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"basename":"myinstance","tunnel_id":"abc123..."}'

# Refresh the TTL
curl -X PATCH https://dev.bas.es/records/myinstance \
  -H "Authorization: Bearer $BASES_DEV_API_KEY"

Development

go build ./...
go test ./...

Deployment

# First install
curl https://code.bas.es/bases/dev/raw/branch/main/deploy.sh | sh -s -- bases-dev

# Update binary
curl https://code.bas.es/bases/dev/raw/branch/main/deploy.sh | sh -s -- bases-dev --update

Add to fismen's Caddyfile:

dev.bas.es {
    reverse_proxy <bases-dev-container-ip>:8080
}

Configuration

Env var Purpose
CF_API_TOKEN Cloudflare API token — requires Zone: DNS: Edit on bas.es and Account: Cloudflare Tunnel: Edit
CF_ZONE_ID Cloudflare zone ID for bas.es
CF_ACCOUNT_ID Cloudflare account ID (used for tunnel creation)
DEV_BASES_API_TOKEN Bearer token for API auth
DEV_BASES_DB SQLite path (default: /var/lib/bases-dev/bases-dev.db)
DEV_BASES_ADDR Listen address (default: :8080)

On the server, secrets live in /etc/bases-dev/env.