Files
inboxos-v1/.env.example
T
cloudinit-bot ae31098d9a ci(workflows): secret-redaction filter for 9 secret env vars (REQ-INB-56)
---ci---
project: inboxos
phase: 1
milestone: v1.4
status: execute
wave: 1
task: T7
---/ci---
2026-06-09 14:09:29 +00:00

151 lines
8.6 KiB
Bash

# InboxOS — Environment Configuration
# Copy to .env and fill in secrets
# cp .env.example .env
# ── NocoDB ──────────────────────────────────────────────
NOCODB_JWT_SECRET=change-me-to-a-random-string
NOCODB_BASE_URL=https://noco.cloudinit.dev
NOCODB_API_TOKEN=change-me-to-a-nocodb-api-token
NOCODB_PROJECT_ID=change-me-to-nocodb-project-id
# NOCODB_MODULE_TABLES is a JSON object that maps each module name
# returned by `inboxos:classify` to the NocoDB table id that should
# receive its extraction record. Phase 2 (INB-4) is responsible for
# populating this; an empty map is tolerated (the pipeline will
# log `module_table_missing` and dead-letter the message).
#
# Example:
# NOCODB_MODULE_TABLES='{"finance":"tbl_finance_xxx","crm":"tbl_crm_yyy","intel":"tbl_intel_zzz","promotions":"tbl_promo_www"}'
NOCODB_MODULE_TABLES='{"finance":"tbl_finance_placeholder","crm":"tbl_crm_placeholder","intel":"tbl_intel_placeholder","promotions":"tbl_promo_placeholder"}'
# ── SeaweedFS (S3-compatible object store) ──────────────
# Used for raw .eml archival and pipeline state (checkpoints).
SEAWEEDFS_S3_ENDPOINT=https://storage.cloudinit.dev
SEAWEEDFS_S3_ACCESS_KEY=change-me-to-a-seaweedfs-access-key
SEAWEEDFS_S3_SECRET_KEY=change-me-to-a-seaweedfs-secret-key
SEAWEEDFS_S3_BUCKET=inboxos
# ── Papra ────────────────────────────────────────────────
PAPRA_AUTH_SECRET=change-me-to-a-random-string
PAPRA_WEBHOOK_SECRET=change-me-to-another-random-string
PAPRA_BASE_URL=https://papra.cloudinit.dev
PAPRA_API_TOKEN=change-me-to-a-papra-api-token
PAPRA_ORGANIZATION_ID=change-me-to-papra-org-id
# ── Ollama ──────────────────────────────────────────────
# OLLAMA_HOST=0.0.0.0
# Base URL the OpenCode CLI uses to reach Ollama. Same value is
# injected into Gitea Action secrets as OLLAMA_BASE_URL.
OLLAMA_BASE_URL=https://ollama-frp.cloudinit.dev/v1
# ── Gitea ───────────────────────────────────────────────
# GITEA__server__DOMAIN=gitea.cloudinit.dev
# Base URL for the Gitea REST API. Inside the gitea-runner container
# this is the compose service name; from a host or external agent
# use the public hostname (https://git.cloudinit.dev).
GITEA_INSTANCE_URL=http://gitea:3000
# HTTP Basic Auth credentials for any code that calls the Gitea
# REST API via pipelines.common.gitea_request. We use Basic Auth
# rather than a personal access token because Gitea does not
# return the plaintext of a freshly created access token through
# the API — Basic Auth is the only fully headless path. See
# docs/gitea-actions.md §5 for the rationale.
GITEA_USER=cto
GITEA_PASS=change-me-to-the-gitea-service-account-password
# Registration token from Gitea → Site Administration → Actions → Runners
# → "Create new runner". This is a one-time secret the runner uses to
# register itself; the runner then receives a long-lived token that
# lives in the gitea-runner-data volume.
GITEA_RUNNER_REGISTRATION_TOKEN=change-me-to-a-gitea-runner-registration-token
# Registration token for the second runner (gitea-runner-2). Generate a
# fresh one from the same Gitea UI — each runner needs its own token.
# Stored long-lived in the gitea-runner-2-data volume. See INB-33 for
# the rationale (live + historical parallelism on the same host).
GITEA_RUNNER_REGISTRATION_TOKEN_2=change-me-to-a-second-gitea-runner-registration-token
# ── IMAP (Live Pipeline) ────────────────────────────────
# Use a Gmail App Password, not the account password. The Gmail
# account should have IMAP enabled in its forwarding/IMAP settings.
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
IMAP_USER=inboxos.dummy@gmail.com
IMAP_PASSWORD=change-me-to-a-gmail-app-password
IMAP_USE_SSL=true
IMAP_MAILBOX=INBOX
# ── OpenCode (executed by the Gitea Actions runner) ─────
# OPENCODE_BIN is the path to the `opencode` binary on the runner.
# OPENCODE_PROMPT_DIR is where version-controlled extraction prompts
# live (e.g. inboxos:extract-finance.md under .opencode/commands/).
OPENCODE_BIN=opencode
OPENCODE_PROMPT_DIR=./.opencode/commands
# Optional overrides for the OpenCode command names. Defaults match
# the prompts checked into the repo, so these are only needed if you
# rename the prompt files.
# INBOXOS_CLASSIFY_COMMAND=inboxos:classify
# INBOXOS_EXTRACT_COMMAND_PREFIX=inboxos:extract-
# ── Pipeline tunables ──────────────────────────────────
# LOG_LEVEL=INFO
# INBOXOS_BODY_CHARS=2000 # cap on body text sent to the LLM (2000 ~= 500 tokens)
# INBOXOS_LLM_MAX_TOKENS=4096 # LLM completion budget; 1024 was too tight for
# # the 11-field extract schema on rich emails
# # (see INB-21).
# INBOXOS_LLM_MODEL and INBOXOS_LLM_MODEL_EXTRACT are pinned to gemma4:e4b. The legacy two-model split (cheap classify + larger extract) was retired in v1.0; REQ-INB-11 forbids a model-escalation chain.
# INBOXOS_LLM_MODEL=gemma4:e4b # canonical pin per REQ-INB-11 (do not change in production)
# INBOXOS_LLM_MODEL_EXTRACT=gemma4:e4b # same as INBOXOS_LLM_MODEL; the legacy two-model split was retired in v1.0
# INBOXOS_LLM_TIMEOUT=120 # seconds per LLM call
# ── Workflow tunables (REQ-INB-33) ──────────────────────
# These env vars are referenced by the Gitea Actions workflows
# (.gitea/workflows/live-pipeline.yml, historical-pipeline.yml,
# ci-pr.yml) but are not surfaced in the example file. Defaults
# below match the workflow-baked defaults; uncomment + edit to
# override locally.
# OLLAMA_API_KEY="" # empty by default; Ollama local is
# unauthenticated. Set only if your
# Ollama is FRP-tunneled and auth-gated.
# INBOXOS_LLM_BACKEND=ollama # default; the v1.0+ production path
# is Ollama. The "opencode" backend is
# wired in pipelines/common.py::
# opencode_run_command but documented
# as offline-tests-only (common.py:455-461);
# do not flip the default without
# reading the docstring.
# PAPRA_DRY_RUN=true # v1.0+v1.1+v1.2 default. Set to
# "false" to enable live Papra
# writes (the Phase 6 / future-v1.x
# gate per docs/papra-write-policy.md).
# PAPRA_BODY_WRITE_MODULES=crm,finance,legal # modules whose bodies
# (not just attachments)
# get written to Papra
# on the post-classify
# pass.
# PAPRA_METADATA_ONLY_MODULES=intel,promotions # modules whose Papra
# write is metadata-only
# (no body upload).
# MBOX_BUCKET= # historical pipeline's S3 bucket for
# the .mbox source. Defaults to
# $SEAWEEDFS_S3_BUCKET if unset.
# OPENCODE_NPM_VERSION=latest # historical pipeline's opencode CLI
# version (the opencode backend is
# offline-tests-only in production
# but the env var is still referenced
# by pipelines/common.py).
# ── end Workflow tunables ──────────────────────────────
# ── v1.4 notes ──────────────────────────────────────────
# The workflow YAML auto-masks the above secret values in CI
# logs via `::add-mask::` (REQ-INB-56). Do not echo them in
# custom `run:` steps; the mask only protects values Gitea
# Actions sees, not values that are echoed in plain text.