refactor(docs): sweep DA_* env vars + surviving da-verbs in docs/*.md (Task 0.5 fix)
This commit is contained in:
parent
1563b05f2e
commit
ed371c84d1
8 changed files with 33 additions and 33 deletions
|
|
@ -40,7 +40,7 @@ KEBOOLA_PROJECT_ID=12345
|
||||||
|
|
||||||
Or configure via the admin UI (`/admin/tables`) or CLI:
|
Or configure via the admin UI (`/admin/tables`) or CLI:
|
||||||
```bash
|
```bash
|
||||||
da admin register-table --source-type keboola --bucket "in.c-crm" --table "company" --query-mode local
|
agnes admin register-table --source-type keboola --bucket "in.c-crm" --table "company" --query-mode local
|
||||||
```
|
```
|
||||||
|
|
||||||
### How it works
|
### How it works
|
||||||
|
|
@ -113,18 +113,18 @@ optional sync schedule. Submit runs `/api/admin/register-table/precheck` first
|
||||||
(round-trips `bigquery.Client.get_table` to confirm the table exists and the SA
|
(round-trips `bigquery.Client.get_table` to confirm the table exists and the SA
|
||||||
can see it), surfaces the row count + size + column count, then commits.
|
can see it), surfaces the row count + size + column count, then commits.
|
||||||
|
|
||||||
**CLI** — `da admin register-table`:
|
**CLI** — `agnes admin register-table`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Dry-run: validate + check the source exists, no DB write.
|
# Dry-run: validate + check the source exists, no DB write.
|
||||||
da admin register-table orders \
|
agnes admin register-table orders \
|
||||||
--source-type bigquery \
|
--source-type bigquery \
|
||||||
--bucket analytics \
|
--bucket analytics \
|
||||||
--source-table orders \
|
--source-table orders \
|
||||||
--dry-run
|
--dry-run
|
||||||
|
|
||||||
# Commit
|
# Commit
|
||||||
da admin register-table orders \
|
agnes admin register-table orders \
|
||||||
--source-type bigquery \
|
--source-type bigquery \
|
||||||
--bucket analytics \
|
--bucket analytics \
|
||||||
--source-table orders \
|
--source-table orders \
|
||||||
|
|
@ -146,7 +146,7 @@ Not supported in M1. The register endpoint rejects any `source_table` containing
|
||||||
For queries that JOIN local data with BigQuery results:
|
For queries that JOIN local data with BigQuery results:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
da query --sql "SELECT o.*, t.views FROM orders o JOIN traffic t ON o.date = t.date" \
|
agnes query --sql "SELECT o.*, t.views FROM orders o JOIN traffic t ON o.date = t.date" \
|
||||||
--register-bq "traffic=SELECT date, SUM(views) as views FROM dataset.web GROUP BY 1"
|
--register-bq "traffic=SELECT date, SUM(views) as views FROM dataset.web GROUP BY 1"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,9 @@ Two health endpoints serve different audiences:
|
||||||
| Endpoint | Auth | Response | Use for |
|
| Endpoint | Auth | Response | Use for |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `GET /api/health` | None | `{"status": "ok"}` | Load balancers, Docker `healthcheck`, uptime pings |
|
| `GET /api/health` | None | `{"status": "ok"}` | Load balancers, Docker `healthcheck`, uptime pings |
|
||||||
| `GET /api/health/detailed` | Bearer token | `{"status", "version", "services": {...}}` | Dashboards, alerting rules, `da diagnose`/`da status` CLI |
|
| `GET /api/health/detailed` | Bearer token | `{"status", "version", "services": {...}}` | Dashboards, alerting rules, `agnes diagnose`/`agnes status` CLI |
|
||||||
|
|
||||||
The Docker Compose `healthcheck` uses the minimal endpoint (`curl -sf http://localhost:8000/api/health`). For external monitoring tools (Datadog, Prometheus, UptimeRobot, etc.) that need service-level detail (DuckDB status, sync freshness, user count), point them at `/api/health/detailed` with an `Authorization: Bearer <token>` header. Any authenticated user can call it; a personal access token (`da admin create-pat`) works well for service accounts.
|
The Docker Compose `healthcheck` uses the minimal endpoint (`curl -sf http://localhost:8000/api/health`). For external monitoring tools (Datadog, Prometheus, UptimeRobot, etc.) that need service-level detail (DuckDB status, sync freshness, user count), point them at `/api/health/detailed` with an `Authorization: Bearer <token>` header. Any authenticated user can call it; a personal access token (`agnes admin create-pat`) works well for service accounts.
|
||||||
|
|
||||||
### Scheduler tuning
|
### Scheduler tuning
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,18 @@ For unattended clients (CI, cron, Claude Code), authenticate with a Personal Acc
|
||||||
**Via CLI (requires an interactive session):**
|
**Via CLI (requires an interactive session):**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
da auth token create --name "github-actions" --ttl 365d --raw
|
agnes auth token create --name "github-actions" --ttl 365d --raw
|
||||||
```
|
```
|
||||||
|
|
||||||
The `--raw` flag prints only the token, suitable for piping into a secret store.
|
The `--raw` flag prints only the token, suitable for piping into a secret store.
|
||||||
|
|
||||||
## Use the PAT
|
## Use the PAT
|
||||||
|
|
||||||
Set the `DA_TOKEN` env var:
|
Set the `AGNES_TOKEN` env var:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export DA_TOKEN=<your-token>
|
export AGNES_TOKEN=<your-token>
|
||||||
da query "SELECT 1"
|
agnes query "SELECT 1"
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitHub Actions example
|
### GitHub Actions example
|
||||||
|
|
@ -28,8 +28,8 @@ da query "SELECT 1"
|
||||||
```yaml
|
```yaml
|
||||||
- name: Sync data
|
- name: Sync data
|
||||||
env:
|
env:
|
||||||
DA_TOKEN: ${{ secrets.AGNES_TOKEN }}
|
AGNES_TOKEN: ${{ secrets.AGNES_TOKEN }}
|
||||||
DA_SERVER: https://agnes.example.com
|
AGNES_SERVER: https://agnes.example.com
|
||||||
run: |
|
run: |
|
||||||
pip install data-analyst
|
pip install data-analyst
|
||||||
da sync --all
|
da sync --all
|
||||||
|
|
@ -38,8 +38,8 @@ da query "SELECT 1"
|
||||||
## Revoke
|
## Revoke
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
da auth token list
|
agnes auth token list
|
||||||
da auth token revoke <id|prefix|name>
|
agnes auth token revoke <id|prefix|name>
|
||||||
```
|
```
|
||||||
|
|
||||||
Or from `/tokens` → Revoke.
|
Or from `/tokens` → Revoke.
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
5. Register your tables via the admin API or CLI:
|
5. Register your tables via the admin API or CLI:
|
||||||
```bash
|
```bash
|
||||||
# Via CLI
|
# Via CLI
|
||||||
da admin register-table --source-type keboola --bucket "in.c-crm" --table "company" --query-mode local
|
agnes admin register-table --source-type keboola --bucket "in.c-crm" --table "company" --query-mode local
|
||||||
|
|
||||||
# Or start the server and use the web UI at /admin/tables
|
# Or start the server and use the web UI at /admin/tables
|
||||||
```
|
```
|
||||||
|
|
|
||||||
26
docs/RBAC.md
26
docs/RBAC.md
|
|
@ -100,7 +100,7 @@ No DB migration, no startup hook, no second wiring step in `access-overview` —
|
||||||
Members are added to groups by three sources, distinguished by the `source` column:
|
Members are added to groups by three sources, distinguished by the `source` column:
|
||||||
|
|
||||||
- **`google_sync`** — written by the OAuth callback on every login. The previous Google-sync set is wholesale replaced (DELETE + INSERT) so a removed Workspace membership disappears immediately.
|
- **`google_sync`** — written by the OAuth callback on every login. The previous Google-sync set is wholesale replaced (DELETE + INSERT) so a removed Workspace membership disappears immediately.
|
||||||
- **`admin`** — written by admin actions in the UI (`/admin/access`), CLI (`da admin group add-member …`), or REST (`POST /api/admin/groups/{id}/members`). Survives Google sync. Admin can only delete admin-source rows.
|
- **`admin`** — written by admin actions in the UI (`/admin/access`), CLI (`agnes admin group add-member …`), or REST (`POST /api/admin/groups/{id}/members`). Survives Google sync. Admin can only delete admin-source rows.
|
||||||
- **`system_seed`** — written at deploy time. Used for the `SEED_ADMIN_EMAIL` → Admin-group binding and the auto-Everyone membership of every new user. Never modified at runtime.
|
- **`system_seed`** — written at deploy time. Used for the `SEED_ADMIN_EMAIL` → Admin-group binding and the auto-Everyone membership of every new user. Never modified at runtime.
|
||||||
|
|
||||||
Removing a user from a group via the admin path (UI/CLI/REST) only deletes admin-source rows. To revoke a Google-synced membership, the operator must change the upstream Workspace group instead — Agnes will pick up the change on the user's next login.
|
Removing a user from a group via the admin path (UI/CLI/REST) only deletes admin-source rows. To revoke a Google-synced membership, the operator must change the upstream Workspace group instead — Agnes will pick up the change on the user's next login.
|
||||||
|
|
@ -121,18 +121,18 @@ Removing a user from a group via the admin path (UI/CLI/REST) only deletes admin
|
||||||
### CLI
|
### CLI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
da admin group list
|
agnes admin group list
|
||||||
da admin group create Engineering --description "Eng team"
|
agnes admin group create Engineering --description "Eng team"
|
||||||
da admin group delete Engineering
|
agnes admin group delete Engineering
|
||||||
da admin group members Engineering
|
agnes admin group members Engineering
|
||||||
da admin group add-member Engineering alice@example.com
|
agnes admin group add-member Engineering alice@example.com
|
||||||
da admin group remove-member Engineering alice@example.com
|
agnes admin group remove-member Engineering alice@example.com
|
||||||
|
|
||||||
da admin grant resource-types
|
agnes admin grant resource-types
|
||||||
da admin grant create Engineering marketplace_plugin foundry-ai/metrics-plugin
|
agnes admin grant create Engineering marketplace_plugin foundry-ai/metrics-plugin
|
||||||
da admin grant list --type marketplace_plugin
|
agnes admin grant list --type marketplace_plugin
|
||||||
da admin grant list --group Engineering
|
agnes admin grant list --group Engineering
|
||||||
da admin grant delete <grant-id>
|
agnes admin grant delete <grant-id>
|
||||||
```
|
```
|
||||||
|
|
||||||
All subcommands authenticate via PAT and exit non-zero on API errors.
|
All subcommands authenticate via PAT and exit non-zero on API errors.
|
||||||
|
|
@ -160,7 +160,7 @@ Every mutation writes an audit log entry (`user_group.created`, `resource_grant.
|
||||||
1. Creates a `users` row for that email if missing (with `password_hash` from `SEED_ADMIN_PASSWORD` if provided).
|
1. Creates a `users` row for that email if missing (with `password_hash` from `SEED_ADMIN_PASSWORD` if provided).
|
||||||
2. Adds an Admin-group membership with `source='system_seed'`.
|
2. Adds an Admin-group membership with `source='system_seed'`.
|
||||||
|
|
||||||
The hook is idempotent — re-running deploy does not duplicate or revoke. To add additional initial admins post-deploy, log in as the seed admin and use `/admin/access` or `da admin group add-member Admin <email>`.
|
The hook is idempotent — re-running deploy does not duplicate or revoke. To add additional initial admins post-deploy, log in as the seed admin and use `/admin/access` or `agnes admin group add-member Admin <email>`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ ai-data-analyst/
|
||||||
│ ├── auth/ Auth providers (JWT, Google OAuth, email magic link, password)
|
│ ├── auth/ Auth providers (JWT, Google OAuth, email magic link, password)
|
||||||
│ └── web/ HTML dashboard routes
|
│ └── web/ HTML dashboard routes
|
||||||
├── services/ Standalone background services (scheduler, telegram_bot, ws_gateway, …)
|
├── services/ Standalone background services (scheduler, telegram_bot, ws_gateway, …)
|
||||||
├── cli/ CLI tool (da sync, da query, da admin)
|
├── cli/ CLI tool (da sync, agnes query, agnes admin)
|
||||||
├── scripts/ Utility and migration scripts
|
├── scripts/ Utility and migration scripts
|
||||||
├── config/ Instance configuration templates
|
├── config/ Instance configuration templates
|
||||||
├── tests/ Test suite
|
├── tests/ Test suite
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ If any are missing, `app/instance_config.py` catches the `ValueError`, logs `Cou
|
||||||
| Login works but the user keeps getting re-prompted on the next request | Access-token cookie lost between requests. Common cause: `DOMAIN` unset → `Secure=False` but the browser hit the app over `https://` via a proxy and dropped the cookie for another reason; or `DOMAIN` set but the browser hit `http://`. | Set `DOMAIN=<hostname>` to match the terminator's hostname, and always serve over HTTPS to the browser. |
|
| Login works but the user keeps getting re-prompted on the next request | Access-token cookie lost between requests. Common cause: `DOMAIN` unset → `Secure=False` but the browser hit the app over `https://` via a proxy and dropped the cookie for another reason; or `DOMAIN` set but the browser hit `http://`. | Set `DOMAIN=<hostname>` to match the terminator's hostname, and always serve over HTTPS to the browser. |
|
||||||
| `/login?error=google_not_configured` | `GOOGLE_CLIENT_ID` or `GOOGLE_CLIENT_SECRET` empty in container env. | Inspect `docker compose exec app env \| grep GOOGLE`. |
|
| `/login?error=google_not_configured` | `GOOGLE_CLIENT_ID` or `GOOGLE_CLIENT_SECRET` empty in container env. | Inspect `docker compose exec app env \| grep GOOGLE`. |
|
||||||
| `/login?error=domain_not_allowed` | User's email domain isn't in `auth.allowed_domain`. | Add the domain (CSV) and reload — note that allowed_domain only takes effect when `instance.yaml` validates (see above). |
|
| `/login?error=domain_not_allowed` | User's email domain isn't in `auth.allowed_domain`. | Add the domain (CSV) and reload — note that allowed_domain only takes effect when `instance.yaml` validates (see above). |
|
||||||
| Login succeeds but `/admin/*` returns 403 | New user is not in the `Admin` system group. | Set `SEED_ADMIN_EMAIL` BEFORE first login, or promote via `da admin break-glass grant-admin <email>` (requires shell access to the host — see below). |
|
| Login succeeds but `/admin/*` returns 403 | New user is not in the `Admin` system group. | Set `SEED_ADMIN_EMAIL` BEFORE first login, or promote via `agnes admin break-glass grant-admin <email>` (requires shell access to the host — see below). |
|
||||||
|
|
||||||
## Admin promotion (when `SEED_ADMIN_EMAIL` was missed)
|
## Admin promotion (when `SEED_ADMIN_EMAIL` was missed)
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ Use the break-glass CLI command. It writes directly to `system.duckdb` without H
|
||||||
```bash
|
```bash
|
||||||
cd <install-dir>
|
cd <install-dir>
|
||||||
docker compose stop app scheduler
|
docker compose stop app scheduler
|
||||||
da admin break-glass grant-admin me@example.com
|
agnes admin break-glass grant-admin me@example.com
|
||||||
docker compose start app scheduler
|
docker compose start app scheduler
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ memberships, used by:
|
||||||
- RBAC authorization (`app/auth/access.py`) — `require_resource_access`
|
- RBAC authorization (`app/auth/access.py`) — `require_resource_access`
|
||||||
checks group grants
|
checks group grants
|
||||||
- Admin UI (`/admin/access`) — member lists, grant counts
|
- Admin UI (`/admin/access`) — member lists, grant counts
|
||||||
- CLI (`da admin group members`) — group membership queries
|
- CLI (`agnes admin group members`) — group membership queries
|
||||||
- Marketplace filtering (`src/marketplace_filter.py`) — plugin access
|
- Marketplace filtering (`src/marketplace_filter.py`) — plugin access
|
||||||
based on group grants
|
based on group grants
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue