Workbook

GeneData Administrator

You own: tenant lifecycle, quotas, billing, user provisioning, and the platform-side toggles that let / prevent each tenant from doing things in GeneFlow.

What's new for you

WasNow in GeneFlow
Manual quota trackingCustomerTenantSettings.geneflow enforced in middleware
Per-tenant cost reports built from logscost_usd rolled up from gf_runs + gf_inference_logs
User scope = read or writeFive distinct scopes (`geneflow:readwritetransitionserveadmin`)

Workflow 1 — Onboard a new tenant

# 1. Create tenant + quotas
genedata tenants create ACME \
  --display-name "ACME Corp" \
  --quota-runs-per-hour 1000 \
  --quota-endpoints 100 \
  --quota-artifact-gib 1000 \
  --data-residency-region us-east-1

# 2. Provision IAM (AWS IRSA)
aws iam create-role --role-name geneflow-ACME ...
helm upgrade --reuse-values genedata \
  --set "global.agentRuntime.runnerIamRoleArn=arn:aws:iam::123:role/geneflow-ACME"

# 3. Create tenant admin user + PAT
genedata users create admin@acme.com --tenant ACME --scope geneflow:admin
genedata auth issue-token --user admin@acme.com --scope geneflow:admin

# 4. Verify
gfctl --tenant ACME experiments list      # should be empty, no errors

Workflow 2 — Adjust quotas

genedata tenants update ACME \
  --quota-runs-per-hour 5000 \
  --quota-endpoints 500

Or via UI: /admin/tenants/ACME/quotas.

Workflow 3 — Cost rollup per tenant per month

SELECT
  tenant_id,
  date_trunc('month', day) AS month,
  SUM(run_cost_usd)        AS train_cost,
  SUM(inference_cost_usd)  AS infer_cost,
  SUM(endpoint_idle_cost_usd) AS idle_cost,
  SUM(total_geneflow_cost_usd) AS total
FROM fct_geneflow_cost_daily
WHERE tenant_id = 'ACME' AND day >= now() - INTERVAL '90 days'
GROUP BY 1, 2 ORDER BY 2 DESC;

(Source view from AE workbook.)

Workflow 4 — Token + scope hygiene

# Inspect a user's tokens
gfctl auth tokens list --user mle@acme.com

# Revoke
gfctl auth tokens revoke --id tok_abc...

# Rotate the system token (jobs-service, serving pods)
aws secretsmanager update-secret --secret-id genedata/jobs-system-token-ACME \
  --secret-string "$(genedata auth issue-system-token --scope internal:ingest --tenant ACME)"
kubectl rollout restart deploy/jobs-service deploy/geneflow-service -n genedata-ACME

Workflow 5 — Suspend a tenant

genedata tenants update ACME --status suspended
# Effect: all gf_* writes return 403; reads still work; serving pods stop scaling

Workflow 6 — Decommission a tenant

# 1. Backup
genedata tenants export ACME --to s3://genedata-archive/ACME/

# 2. Wipe — irreversible
genedata tenants delete ACME --confirm "I understand this is irreversible"
# This:
#   - Deletes all gf_* rows where tenant_id='ACME'
#   - Deletes the S3 prefix s3://…/ACME/
#   - Deletes the namespace
#   - Marks audit log entries as tombstoned (rows retained for compliance)

Common gotchas

  • Don't bump quotas via SQL — go through the API so audit catches it.
  • System tokens are tenant-scoped — one per tenant. Don't reuse across tenants.
  • Decommission preserves audit log — by design, for compliance.

Where to go next