Skip to content

Configuration

All TipOff components are configured via environment variables (12-factor).

The agent is the component you self-host. It connects to the hosted server and forwards action events to local services.

Terminal window
TIPOFF_AGENT_API_KEY=sk_your_source_key \
TIPOFF_AGENT_GRPC_URL=grpc.tipoff.dev:443 \
TIPOFF_AGENT_ADAPTERS_DIR=./adapters \
./tipoff-agent
VariableDefaultDescription
TIPOFF_AGENT_API_KEYSource API key (sk_...) — authenticates the gRPC stream
TIPOFF_AGENT_GRPC_URLServer gRPC address (e.g. grpc.tipoff.dev:443)
TIPOFF_AGENT_ADAPTERS_DIRadaptersDirectory of *.yaml adapter files
TIPOFF_AGENT_HTTP_ADDR:8080Listen address for the agent’s webhook HTTP server

Action payloads include a state object that round-trips through the iOS device (notification → device → action callback). Signing prevents tampering with this metadata in transit.

Terminal window
TIPOFF_AGENT_SIGNING_KEY=your-hmac-secret \
TIPOFF_AGENT_SIGNING_KEY_PREVIOUS=old-hmac-secret \
./tipoff-agent
VariableDefaultDescription
TIPOFF_AGENT_SIGNING_KEY(empty)HMAC-SHA256 key for signing action payloads. If empty, signing is disabled.
TIPOFF_AGENT_SIGNING_KEY_PREVIOUS(empty)Previous key for rotation grace period

How it works: At notification time, the agent signs each action’s state object. The signature is embedded in the notification metadata and travels to the device and back. When an action event arrives, the signature is verified before the action is executed.

Key rotation: Set the new key as SIGNING_KEY and the old key as SIGNING_KEY_PREVIOUS. The agent tries the current key first, then falls back to the previous key. Once all in-flight notifications (signed with the old key) have been actioned or expired, remove SIGNING_KEY_PREVIOUS.

VariableDefaultDescription
TIPOFF_AGENT_ERROR_TARGET(empty)Fallback TipOff user ID for error notifications when no adapter-level error handler matches
TIPOFF_AGENT_CATALOG_REFRESH5mHow often to re-fetch the action catalog from the server. Set to 0 to disable.

A production agent deployment for Donetick and Vikunja adapters:

Terminal window
TIPOFF_AGENT_API_KEY=sk_abc123... \
TIPOFF_AGENT_GRPC_URL=grpc.tipoff.dev:443 \
TIPOFF_AGENT_ADAPTERS_DIR=/etc/tipoff/adapters \
TIPOFF_AGENT_HTTP_ADDR=:8080 \
TIPOFF_AGENT_SIGNING_KEY=hmac-secret-here \
TIPOFF_AGENT_ERROR_TARGET=user_abc \
TIPOFF_AGENT_CATALOG_REFRESH=5m \
TIPOFF_LOG_LEVEL=info \
TIPOFF_LOG_FORMAT=json \
DONETICK_URL=https://donetick.local \
DONETICK_API_KEY=dt_key_here \
DONETICK_WEBHOOK_SECRET=webhook-secret-here \
VIKUNJA_URL=https://vikunja.local \
VIKUNJA_TOKEN=vikunja-api-token \
VIKUNJA_WEBHOOK_SECRET=vikunja-webhook-secret \
./tipoff-agent

These variables configure the hosted server. Most integrators don’t need these — they’re documented for operators and contributors.

VariableDefaultDescription
TIPOFF_PORT8080HTTP API port
TIPOFF_GRPC_PORT9091gRPC agent streaming port
TIPOFF_METRICS_PORT9090Prometheus metrics port
TIPOFF_DB_PATHtipoff.dbSQLite database path
TIPOFF_REDIS_URL(empty)Redis URL; if empty, uses in-memory queue
TIPOFF_LOG_LEVELinfodebug info warn error
TIPOFF_LOG_FORMATjsonjson or text
VariableDefaultDescription
TIPOFF_APNS_KEY_IDAPNs auth key ID
TIPOFF_APNS_TEAM_IDApple Developer team ID
TIPOFF_APNS_KEY_PATHPath to .p8 key file
TIPOFF_APNS_BUNDLE_IDApp bundle identifier
TIPOFF_APNS_ENVIRONMENTproductionproduction or sandbox
VariableDefaultDescription
TIPOFF_RESEND_API_KEY(empty)Resend API key for magic link emails
TIPOFF_RESEND_FROMTipOff <noreply@tipoff.dev>From address for magic link emails
TIPOFF_AUTH_BASE_URLhttps://api.tipoff.devBase URL for magic link callback
TIPOFF_CORS_ORIGINS(empty)Comma-separated allowed CORS origins
TIPOFF_SESSION_TTL720hSession lifetime (30 days)
TIPOFF_MAGIC_LINK_TTL15mMagic link token lifetime
TIPOFF_COOKIE_DOMAIN.tipoff.devDomain attribute for session cookies
VariableDefaultDescription
TIPOFF_NOTIFICATION_TTL168hHow long un-actioned notifications live (7 days)
TIPOFF_CLEANUP_INTERVAL5mHow often the TTL cleanup runs
TIPOFF_RATELIMIT_ENABLEDtrueRate limiting kill switch