Config as code
Keep a project in your repo and apply it to any IvaraBase server - a teammate’s laptop, staging, or production - with a plan you can review first.
my-app/ ivarabase.yaml .env # secret values (keep out of git) migrations/ # *.sql, applied in file-name order, each in one transaction functions/ send-email/ # one folder per function (index.ts + any other files) index.ts lib/templates.tsproject: shop # created if it doesn't existname: Shopmigrations: migrationsfunctions_dir: functionsfunctions: # optional per-function settings stripe-webhook: { verify_jwt: false } nightly-report: { schedule: "0 3 * * *", timeout_s: 120 }secrets: STRIPE_KEY: ${STRIPE_KEY} # from the environment or .env next to this fileauth: site_url: https://myapp.com redirect_urls: [http://localhost:3000/*] confirm_email: true password_min_length: 8 google: { enabled: true, client_id: 123.apps.googleusercontent.com, client_secret: ${GOOGLE_CLIENT_SECRET} } apple: # see docs/APPLE.md enabled: true client_id: com.myapp.web # Services ID (web sign-in) team_id: ABCDE12345 key_id: XYZ9876543 private_key: ${APPLE_PRIVATE_KEY} # the .p8 contents; literal \n is fine in .env bundle_ids: [com.myapp.ios] # native apps (signInWithIdToken) smtp: { host: smtp.resend.com, port: 587, user: resend, pass: ${SMTP_PASS}, from_email: no-reply@myapp.com }storage: buckets: avatars: { public: true, file_size_limit: 1MB, allowed_mime_types: [image/*] } documents: { public: false }Commands
Section titled “Commands”ivarabase login --url https://base.example.com --token ivb_...ivarabase export --project shop # start from an existing projectivarabase plan # what would changeivarabase apply # asks, then applies (--yes for CI)ivarabase apply --prune # also delete functions/secrets/buckets not in the filesivarabase db types --project shop --out src/database.types.ts- Migrations are append-only. A migration that was applied is matched by name (or by
identical SQL, so renamed exports still match). Editing an applied migration is an error -
applyrefuses to run and nothing changes. Add a new migration instead. - Steps run through the normal API: the token’s level and project scope apply, every change is in the audit log, and destructive SQL (DROP/TRUNCATE/unbounded DELETE) needs the same confirmation as anywhere else.
- Deletions only with
--prune, and a token withoutallow_destructivegets an approval request instead - the owner approves it in the UI, then you runapplyagain. - Secrets never leave the server:
plancompares them on the server and only reports “create” or “update”;exportwrites${NAME}placeholders. applystops at the first failed step and reports where.
The same operations are available to agents over MCP as config_plan, config_apply and
config_export (the spec is JSON instead of files).
CI example (GitHub Actions)
Section titled “CI example (GitHub Actions)”- run: curl -fsSL -o ivarabase https://YOUR-HOST/ivarabase-linux-amd64 && chmod +x ivarabase- run: ./ivarabase apply --yes env: IVARA_URL: https://base.example.com IVARA_TOKEN: ${{ secrets.IVARA_TOKEN }} # write-level token scoped to this project STRIPE_KEY: ${{ secrets.STRIPE_KEY }}Compatibility suite
Section titled “Compatibility suite”make compat creates a test project from tests/compat/project/ivarabase.yaml and runs the
real supabase-js client against it: REST, auth, storage and functions (52 checks).