20. CLI Tool

Alex wants to manage projects, run queries, and test RLS policies from the terminal.

The Eurobase CLI lets you manage your projects, database, storage, vault, and more from the command line. Install it via Homebrew or download the Go binary.

Installation

brew install stgime/tap/eurobase
# or download a binary: github.com/STGime/homebrew-tap/releases
# macOS manual download only: xattr -d com.apple.quarantine ./eurobase (not notarized; brew installs unaffected)

Without Homebrew (CI, agents, Linux servers), download the binary for your platform (macOS or Linux, amd64 or arm64):

VER=0.6.1 # latest: github.com/STGime/homebrew-tap/releases
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')
BASE=https://github.com/STGime/homebrew-tap/releases/download/cli-v${VER}
TGZ=eurobase_${VER}_${OS}_${ARCH}.tar.gz
curl -fsSLO "$BASE/$TGZ" && curl -fsSLO "$BASE/eurobase_${VER}_checksums.txt"
grep " $TGZ\$" eurobase_${VER}_checksums.txt | shasum -a 256 -c -
tar xzf "$TGZ" && sudo mv eurobase /usr/local/bin/ # or anywhere on your PATH
eurobase version

The Eurobase CLI is not on npm. The npm package named eurobase is an unrelated product from another publisher. It describes itself as the official Eurobase CLI, but it isn't ours and doesn't work with your Eurobase projects. Don't install it or run npx eurobase, and never give it a Eurobase token. Install only from Homebrew (stgime/tap/eurobase) or the releases at github.com/STGime/homebrew-tap. If you set up a coding agent, tell it the same. (Our only npm package is the app SDK, @eurobase/sdk.)

Getting started

# Log in to your account
eurobase login
# List your projects
eurobase projects list
# Set the active project
eurobase switch my-project
# See project status and usage
eurobase status

In CI or scripts, log in with a personal access token instead: eurobase login --token "$EUROBASE_PAT". A project token selects its project automatically and can run the project commands with the access you gave it. A project token can't create or delete projects: do that in the console (or after eurobase login, if your account signs in with a password only, without a passkey or SSO).

Where the CLI keeps your login, and working with several projects

Every command reads one file, $HOME/.eurobase/config.json (mode 600): your token, the active project and the API URL. eurobase login and eurobase switch write it; nothing is kept in the macOS Keychain or any other credential store, and the CLI finds the file only through HOME. There’s no profile option or --project flag yet, so to keep a test project fully apart from production, give it its own directory as HOME for the CLI, and log in there with a token scoped to that project:

HOME=~/.eurobase-test eurobase login --token "$TEST_PROJECT_TOKEN" # selects the token's project
HOME=~/.eurobase-test eurobase status # confirm the project
HOME=~/.eurobase-test eurobase migrations up

Setting HOME per command keeps the rest of your shell unchanged, and the test login stays in ~/.eurobase-test for next time. A project token is refused for every other project, so even a mixed-up configuration can’t reach production. eurobase migrations up reads ./migrations/*.sql from the current directory.

Command reference

CommandDescription
Auth & Projects
loginSign in with email and password
logoutClear stored credentials
versionPrint the CLI version
projects listList all projects
projects create <name>Create a new project
projects delete <id>Delete a project (requires --confirm)
switch <slug>Set active project
statusShow usage and plan info
Database
db tablesList tables (excludes system tables)
db schema [table]Show columns and types
db objectsList views, sequences and types
db query "SQL"Execute SQL and print results
db create-table <name> <col:type>...Create a table with RLS preset
db add-column <table> <col:type>Add a column
db drop-column <table> <column>Drop a column
db drop-table <name>Drop a table
db dumpExport schema as text
Schema Migrations
migrations new <name>Create the next numbered migration file in ./migrations
migrations upApply pending migrations to the active project (idempotent)
migrations statusLocal files vs applied versions
Keys & Config
keys showDisplay API keys
keys regenerateRotate API keys
initGenerate .env, CLAUDE.md, .cursorrules
Logs
logsShow recent request logs
logs --tailStream logs in real time
Vault
vault listList secret names
vault get <name>Get decrypted value
vault set <name> <value>Store a secret
vault delete <name>Delete a secret
Edge Functions (serverless TypeScript/JavaScript)
edge-functions listList deployed edge functions
edge-functions deploy <name>Deploy from functions/<name>.ts (or --file); --no-verify-jwt for public functions
edge-functions get <name>Show details and source code
edge-functions invoke <name>Invoke with optional --data JSON body
edge-functions logs <name>View invocation logs
edge-functions delete <name>Delete an edge function
Cron & RPC Functions
cron listList scheduled jobs
cron logs <id>Show run history
functions listList RPC functions (Postgres) with their arguments
functions get <name> [--args "…"]Print the function's CREATE OR REPLACE statement (next CLI release)
functions create <name>Create from file
functions delete <name>Drop function
Storage
storage lsList files
storage upload <local> <key>Upload a file
storage download <key> <local>Download a file
storage delete <key>Delete a file
storage url <key>Generate signed URL
Compliance
compliance reportGenerate the DPA / sub-processor report
compliance sub-processorsList active sub-processors

Testing RLS policies

Test your policies the way your users actually reach your data: as an authenticated client. Create a few test end-users in a separate project, sign each one in, and exercise the SDK (or REST API) with that user's access token. Row-Level Security is evaluated under the same non-owner role as in production, so what a test user can read or write is exactly what a real client would get.

import { createClient } from '@eurobase/sdk'

const eb = createClient({ url: PROJECT_URL, apiKey: PUBLIC_KEY })

// Sign in as a seeded test user, then read/write under their session.
await eb.auth.signIn({ email: 'alice@example.test', password: '...' })

const { data: mine } = await eb.db.from('tasks').select('*')        // only Alice's rows
const { error } = await eb.db.from('tasks').update(BOB_TASK_ID, { title: 'x' })  // RLS blocks updating Bob's row

// Sign out -> anonymous: a protected table returns nothing.
await eb.auth.signOut()
const { data: anon } = await eb.db.from('tasks').select('*')        // []

Each session carries its identity automatically: the platform sets app.end_user_id and app.end_user_role for the request, which your policies read through auth_uid(), auth_role() and is_service_role(). Confirm what a session resolves to with GET /v1/auth/user using that user's token. The Row-Level Security chapter has the policy patterns and a "Test it from the SDK" walkthrough.

Why not test from inside the database (e.g. pgTAP)? Every statement you run on Eurobase goes through a non-owner, RLS-enforced role, one statement at a time, with no transaction control — the same constraints that make your RLS guarantees trustworthy. Testing policies from inside the database would mean relaxing exactly that boundary. Our EU-managed Postgres also ships a vetted, security-reviewed set of extensions, and in-database test frameworks such as pgTAP aren't part of it. Testing as an authenticated client covers the whole path — sign-in → identity → policy → response — which is what your users actually exercise.