Organization administration
Members, roles and grants, data connections, saved queries, service connectors, analytics, and observability logs.
Management commands are org-scoped. They work from any directory after railcode login and
need no app or railcode.json. Most references accept a name, slug, or email, or a UUID.
Owner and admin permissions are enforced on the server. A 403 marks an authority boundary.
Do not work around it with another credential.
Work in this order: inspect with the matching read command, apply the narrowest mutation, then verify with the read command again.
Members
railcode members list
railcode members set-role <email|uuid> --role admin|member
railcode members remove <email|uuid>Any member may list members. Mutations require admin authority. The owner tier is not
assignable through set-role.
There is no CLI command that creates a member. A new person joins through the invite
flow in the web app, and set-role then adjusts their tier.
Custom roles and grants
railcode roles list
railcode roles create --name <name> [--description <text>]
railcode roles update <role> [--name <name>] [--description <text>]
railcode roles delete <role>
railcode roles add-member <role> <email|uuid>
railcode roles remove-member <role> <email|uuid>
railcode roles grants
railcode roles grant --subject <org|role:X|user:X> --resource <type> --ids <a,b>
railcode roles revoke <grant_id>
railcode roles materialize --subject <org|role:X|user:X> --resource <type>
railcode roles effective <email|uuid>
railcode roles catalogGrant resource types: app, llm, email, sc_endpoint, connector, saved_query, and
agent.
Grants are additive. --ids is a comma-separated list and may use *, but prefer explicit
ids. materialize expands wildcard access into the resources that exist now, so future
resources are not included automatically. Inspect the subject and resource first, because it
changes how grants are maintained later.
Use catalog to discover grantable names and effective to verify a member's computed
access.
App authority declared in manifest.yaml is ratified against this same grant model. This is
why a deploy can be blocked for adding authority the deployer does not hold.
Saved queries
railcode query list
railcode query run my_orders --params '{"region":"emea","limit":5}'
railcode query create --name my_orders --connection analytics \
--sql "select * from orders where region = :region limit :limit" \
--params '[{"name":"region","type":"string"},{"name":"limit","type":"int","default":20}]'
railcode query update my_orders --sql-file my_orders.sql
railcode query delete my_ordersCreate, update, and delete are admin-only. list and run are member operations, and
invocation can be grant-gated per query.
Templates use :name placeholders with declared types string, int, float, or bool.
run --params is a JSON object. Create/update --params is an array of parameter
declarations. SQL comes from --sql or --sql-file, never both.
update uses PATCH semantics: omitted fields stay unchanged, and --clear-params declares
none. SQL and param edits bump the version while preserving grants. Delete removes the saved
query and any grants that name it.
The server injects :_ctx_user_id, :_ctx_user_email, and :_ctx_org. Callers cannot
override them. Use those binds for per-caller row scoping that cannot be forged. list
exposes signatures, never SQL text.
Data connections
railcode connections list
railcode connections create --name <n> --kind postgres \
--config-file connection.json --credentials-file credentials.json
railcode connections delete <name|uuid>Create replaces a same-name connection and connects to it before saving.
| Kind | Config | Credentials |
|---|---|---|
postgres | {host, database, username, port?, sslmode?} | {password} |
bigquery | {project_id, dataset} | {service_account_json} |
turso | {url} | {auth_token} |
Inline --config and --credentials are supported, but the file options keep credentials
out of shell history.
Deleting a connection can break saved queries and apps. Inspect dependents first.
If the database sits behind a firewall, allow our IP address first.
Service connectors
railcode connector list --admin # base URL, credential state, enabled state, native key
railcode connector native # presets and their credential fields
railcode connector enable <key> --credentials-file credentials.json
railcode connector create --name <n> --base-url <url> --auth-type bearer \
--auth-config-file auth.json --methods GET,POST --description <text>
railcode connector delete <name|uuid>enable creates or rotates a native connector credential. Use --disabled to create one
disabled, and restrict --methods to the verbs required.
The member-facing connector list, docs, and fetch are invocation tools. fetch can
cause downstream side effects, so use it as a deliberate verification call.
If the API only accepts known addresses, allow our IP address.
Analytics
railcode analytics <app> [--range 7d|30d|90d]Default range 30d. Output includes totals, uniques, daily values, top paths, and top
users.
Observability logs
railcode logs <stream> [filters]
railcode logs <stream> <request_id> # full JSON detail| Stream | What it covers | Capability |
|---|---|---|
connector | Data-connection SQL | connection:manage |
service-connector | Proxied HTTP calls | service-connector:manage |
llm | LLM gateway calls | llm:manage |
email | Email gateway sends | email:manage |
agent | Managed-agent runs | agent:manage |
Filters are validated per stream: --app, --user, --connector, --agent,
--source app|agent (LLM only), --status, and --limit <1..500> (default 100).
Per-app backend logs (railcode logs app) are a different surface. They are available to
anyone with edit rights on the app, rather than admin-only. See
deploying.
Working principles
- Grant specific resources instead of
*unless broad access is explicitly intended. - Prefer saved queries over ad-hoc SQL authority.
- Restrict service-connector HTTP methods to what is needed.
- Use the file options for credentials rather than inline flags.
- Propose archiving over deleting when the goal is to retire an app. Archive is inert and reversible; delete is not.
app kv/app filesmutate live tenant data, including individual members' private scopes. Inspect first. Mutate only what was asked for.