Skip to content
Configuration reference

Configuration reference

Framework settings

Read by anetos.New into anetos.AppConfig.

KeyTypeDefaultDescriptionSince
APP_NAMEstringanetosApplication name, added to every log line as appv0.1
APP_ENVdevelopment | testing | staging | productionproductionDeployment environment; also selects .env.<APP_ENV>v0.1
APP_URLURLemptyThe app’s public URL (https://example.com, no path), for links that leave the app: OAuth callbacks (social login), links in emails (mailer.URL)v0.2
APP_DEBUGboolfalseEnables debugging aids. Rejected when APP_ENV=productionv0.1
APP_SHUTDOWN_TIMEOUTduration30sTotal graceful-shutdown budget: components first, then shutdown hooks. Hooks always keep the smaller of 5s and a fifth of it. Keep it at or below your platform’s grace period (Kubernetes default: 30s)v0.1
APP_KEYbase64:… (32 bytes)emptyEncrypts and authenticates session cookies. Required by sessions, which fail at startup without it. Generate one with go tool anetos key:generate. Keep it secretv0.1
APP_PREVIOUS_KEYSlist of keysemptyOld keys that still decrypt, so APP_KEY can be rotated without logging everyone outv0.1
APP_TIMEZONEIANA time zone (Asia/Dhaka)UTCThe app’s zone: the process’s local zone (so time.Now, logs and formatting agree on every machine), the zone of anetos.Now and the default of SCHEDULE_TIMEZONE. Times are stored in UTC whatever it is. Local isn’t allowed. See Times and datesv0.3
APP_LOCALElocale (en, bn, pt-BR)enThe default locale: of requests that ask for no supported one, and of code outside requests. Read by i18n.ForAppv0.3
APP_FALLBACK_LOCALElocaleenWhere a locale’s missing messages come from, after its parents (bn-BD, then bn); the framework’s English messages come lastv0.3
APP_LOCALESlist of localesAPP_LOCALE and every locale with a catalogThe locales requests can ask for. APP_LOCALE must be one of themv0.3
LOCALE_URLnone | prefix | subdomainnoneWhere a request’s locale is in its URL: nowhere (the locale cookie, the session, the signed-in user’s preference, Accept-Language), a path prefix (/bn/about; the default locale has none), or a subdomain (bn.example.com; needs APP_URL). See Translationsv0.3
LOG_LEVELdebug | info | warn | errorinfoMinimum log levelv0.1
LOG_FORMATtext | json | emptyemptyLog format; empty means JSON in production, text elsewherev0.1

APP_ENV defaults to production so that a missing setting fails safe (debug off, JSON logs). The keys have type anetos.Secret, which prints, logs and encodes as [redacted]; use string(cfg.Key) for the value.

Struct tags

Used by config.Bind and config.Get.

TagExampleMeaning
env:"KEY"env:"DB_PORT"Read the field from KEY
env:"KEY,required"env:"DB_URL,required"Error if KEY is missing or empty and there is no default
env:"-"Ignore the field
default:"value"default:"5432"Used when the key is missing or empty
prefix:"P_"prefix:"DB_"On a nested struct (or pointer to struct) without env: prepend P_ to its keys

Untagged nested structs are bound recursively, without a prefix unless one is given. Unexported fields are ignored.

Supported field types

Go typeAccepted values
stringAnything
booltrue/false, 1/0, t/f, yes/no, on/off (any case)
int, int8 … int64Base-10 integers within range
uint, uint8 … uint64Base-10 non-negative integers within range
float32, float64Decimal numbers
time.DurationGo durations: 300ms, 30s, 5m, 1h30m
[]T of the aboveComma-separated; blanks trimmed; empty items dropped
*T of the aboveAllocated only when a value is present
Types whose pointer implements encoding.TextUnmarshalerWhatever UnmarshalText accepts, e.g. slog.Level

Any other type is a binding error.

.env syntax

FormResult
KEY=valuevalue (trailing spaces trimmed)
KEY=value # commentvalue; a # preceded by a space starts a comment
KEY=a#ba#b
export KEY=valuevalue; the export prefix is ignored
KEY= or KEY= # commentempty (treated as unset when binding)
KEY="a\nb ${OTHER}"Double quotes: escapes \n \r \t \" \\ \$, ${VAR} expansion, may span lines
KEY='raw ${OTHER}'Single quotes: literal, may span lines
KEY=${OTHER}-xUnquoted values also expand ${VAR}
# …Comment line

${NAME} resolves with the same priority as the final configuration: the process environment first, then keys defined earlier in the same file, then lower layers (for .env.<APP_ENV>, that’s .env). So a reference always sees the value the application sees. Unknown names become empty; a malformed reference such as ${ or ${A:-default} is an error. $NAME without braces is not expanded. If a key repeats, the last value wins. A UTF-8 byte order mark and CRLF line endings are handled.

Load order

config.Load (called by anetos.New) layers sources, highest priority first:

  1. Process environment
  2. .env.<APP_ENV>: APP_ENV is taken from the process environment, else from .env
  3. .env

anetos.WithConfigDir(dir) changes where the files are read from, and anetos.WithSource(src) replaces the whole mechanism (useful in tests).

HTTP server

Read by web.NewServer (or web.LoadConfig) into web.Config.

KeyTypeDefaultDescriptionSince
HTTP_ADDRstring:8080Listen address. 127.0.0.1:0 picks a free port (tests)v0.1
HTTP_READ_HEADER_TIMEOUTduration10sTime to read request headers (slowloris protection)v0.1
HTTP_READ_TIMEOUTduration30sTime to read the whole requestv0.1
HTTP_WRITE_TIMEOUTduration30sTime to write the responsev0.1
HTTP_IDLE_TIMEOUTduration2mKeep-alive idle timev0.1
HTTP_SHUTDOWN_GRACEduration15sOn shutdown, how long in-flight requests may finish before their contexts are canceled and connections closed. Capped at half of APP_SHUTDOWN_TIMEOUT, so later stages keep time to drainv0.1
HTTP_REQUEST_TIMEOUTduration30sDeadline on each request’s context; expiry gives 503. 0 disablesv0.1
HTTP_MAX_BODYsize10MBMaximum request body (512KB, 10MB, 1GB; units are powers of 1024); larger gives 413. 0 disablesv0.1
HTTP_TRUSTED_PROXIESlist of IPs/CIDRsemptyPeers whose X-Forwarded-For/X-Real-IP are trusted for the client IPv0.1
HTTP_ACCESS_LOGbooltrueOne log line per requestv0.1
HTTP_HEALTH_ROUTESbooltrueServe GET /health/live and GET /health/readyv0.1
HTTP_CORS_ORIGINSlistempty (CORS off)Allowed origins; * for any; https://*.example.com for subdomainsv0.1
HTTP_CORS_METHODSlistGET,HEAD,POST,PUT,PATCH,DELETEAllowed methods for preflightsv0.1
HTTP_CORS_HEADERSlistAccept,Authorization,Content-Type,X-Requested-With,X-Request-IDAllowed request headersv0.1
HTTP_CORS_EXPOSElistX-Request-IDResponse headers readable by browsersv0.1
HTTP_CORS_CREDENTIALSboolfalseAllow cookies; can’t be combined with *v0.1
HTTP_CORS_MAX_AGEduration10mHow long browsers cache preflightsv0.1

Streaming responses lift HTTP_REQUEST_TIMEOUT and HTTP_WRITE_TIMEOUT for themselves: c.Events() (server-sent events, and ai.SSE) does both; other streams use web.WithoutTimeout(ctx) for the request’s context and http.ResponseController’s SetWriteDeadline for the response. They should end when srv.Stopping() is closed, so shutdown doesn’t wait for the grace period.

HSTS (Strict-Transport-Security) is sent automatically when APP_ENV=production; serve production over HTTPS (usually at your proxy or load balancer).

Sessions

Read by session.ForApp (or session.LoadConfig) into session.Config.

KeyTypeDefaultDescriptionSince
SESSION_COOKIEstringanetos_sessionCookie name. A Secure cookie without SESSION_DOMAIN and with path / gets the __Host- prefix. A name you give with __Host- or __Secure- must meet the browser’s rules for itv0.1
SESSION_LIFETIMEduration2hThe session ends after this long without a request (at least 1m)v0.1
SESSION_MAX_LIFETIMEduration168hThe session ends this long after it started or was regenerated (login), however active. 0 disablesv0.1
SESSION_EXPIRE_ON_CLOSEboolfalseBrowser-session cookie: dropped when the browser closesv0.1
SESSION_DOMAINstringempty (this host only)Cookie domain; set it to share the session with subdomainsv0.1
SESSION_PATHstring/Cookie pathv0.1
SESSION_SECUREbooltrue, except development and testingSend the cookie over HTTPS onlyv0.1
SESSION_SAME_SITElax | strict | nonelaxCookie SameSite mode; none requires SESSION_SECURE=truev0.1
SESSION_DRIVERcookie | database | a driver’s name (redis)cookieWhere sessions are kept: the encrypted cookie, or a server-side store (the cookie then holds the encrypted session ID); redis needs redis.SessionDriver() passed to session.ForAppv0.2
SESSION_TABLEstringsessionsThe database driver’s table; pass the same name to session.Migrationsv0.2
SESSION_PREFIXstringAPP_NAME + :session:Starts the store keys of server-side sessions. anetostest sets one per test appv0.2

The cookie is always HttpOnly. Its content is encrypted with APP_KEY; with the cookie driver it holds the whole session, limited to about 4 KB. Server-side sessions are stored, encrypted, under keys starting with SESSION_PREFIX.

Database

Read by db.Connect (or db.LoadConfig(src, prefix), which reads the same keys with a prefix, e.g. ANALYTICS_DB_HOST) into db.Config.

KeyTypeDefaultDescriptionSince
DB_CONNECTIONsqlite | postgres | mysqlsqliteSelects one of the drivers passed to db.Connectv0.1
DB_URLstringemptyComplete connection string in the driver’s format; when set, the five keys below are ignored. Use it for TLS and driver optionsv0.1
DB_HOSTstring127.0.0.1Server host (PostgreSQL, MySQL)v0.1
DB_PORTintdriver default (5432, 3306)Server portv0.1
DB_DATABASEstringempty; SQLite: database/app.dbDatabase name, or the SQLite file (:memory: for an in-memory database)v0.1
DB_USERNAMEstringemptyUserv0.1
DB_PASSWORDstringemptyPasswordv0.1
DB_MAX_OPEN_CONNSint25Maximum open connections (in-memory SQLite always uses 1)v0.1
DB_MAX_IDLE_CONNSint25Maximum idle connections kept for reusev0.1
DB_CONN_MAX_LIFETIMEduration30mConnections are replaced after this longv0.1
DB_CONN_MAX_IDLE_TIMEduration5mIdle connections are closed after this longv0.1
DB_LOG_QUERIESboolon when APP_ENV=developmentLog every query, with its arguments and duration, at debug levelv0.1
DB_SLOW_QUERYduration500msLog queries taking at least this long as warnings (without arguments). 0 disablesv0.1
DB_REPEATED_QUERIESint5 when APP_ENV is development or testing, off elsewhereWarn when a unit of work (a request, a job, a listener, a task) runs the same query this many times or more: an N+1. 0 disables; otherwise at least 2. See Find N+1 queriesv0.2
DB_ALLOW_LOCAL_TIMEZONEboolfalseAccept a database session time zone other than UTC (set in DB_URL), which the app otherwise refuses at boot so the database never writes local times next to the app’s UTC ones. For a legacy database whose times are local; the app still writes UTCv0.3

Search

KeyTypeDefaultDescriptionSince
SEARCH_LANGUAGEsimple | a languagesimpleHow search matches words: simple as written, in any language; english (PostgreSQL, SQLite) also matches their other forms; on PostgreSQL any text search configuration (german, french…). MySQL has simple only. Search indexes are built for it: change it, then run search:reindexv0.3
SEARCH_RANKINGdefault | bm25defaultOrder of search results: the database’s own ranking, or BM25 (SQLite; PostgreSQL 17+ with the pg_textsearch extension; not MySQL). PostgreSQL needs search:reindex after a changev0.3

The app refuses to start when the database can’t serve these settings, or when a search index was built for other ones (except for migrate… and search:reindex); see Search.

Driver specifics:

  • SQLite connections use WAL journaling, a 5s busy timeout, foreign keys and immediate transactions. The file’s directory is created if missing.
  • SQLite stores times as UTC text in the format of its own CURRENT_TIMESTAMP (2026-09-30 12:00:00.5), so column defaults and values written by the app compare correctly.
  • PostgreSQL sessions use the UTC time zone unless DB_URL sets timezone, which the app then refuses at boot (see DB_ALLOW_LOCAL_TIMEZONE).
  • MySQL connections always read times as UTC time.Time (parseTime=true, loc=UTC) and report matched rows for updates (clientFoundRows=true), also when DB_URL says otherwise; sessions use time_zone='+00:00' unless DB_URL sets it, which the app then refuses at boot (see DB_ALLOW_LOCAL_TIMEZONE).

Cache

Read by cache.ForApp (or cache.LoadConfig) into cache.Config.

KeyTypeDefaultDescriptionSince
CACHE_STOREmemory | database | a driver’s name (redis)memorySelects the store; redis needs redis.CacheDriver() passed to cache.ForAppv0.2
CACHE_PREFIXstringAPP_NAME + :cache:Starts every key, so apps (and other features in Redis) can share a store; cache:clear removes only these keys. anetostest sets one per test appv0.2
CACHE_TABLEstringcacheThe database store’s table; pass the same name to cache.Migrationsv0.2

Queue

Read by queue.ForApp (or queue.LoadConfig) into queue.Config. See Queues.

KeyTypeDefaultDescriptionSince
QUEUE_DRIVERsync | memory | database | a driver’s name (redis)syncWhere jobs are kept; sync runs each job when it is dispatched. redis needs redis.QueueDriver() passed to queue.ForAppv0.2
QUEUE_DEFAULTqueue namedefaultThe queue of jobs dispatched without queue.OnQueue, and of workers without queue.Queues. Lower-case letters, digits and . _ : -, up to 100v0.2
QUEUE_TRIESint ≥ 13Attempts per job, unless its type sets queue.Triesv0.2
QUEUE_TIMEOUTduration1mHow long an attempt may run, unless its type sets queue.Timeoutv0.2
QUEUE_BACKOFFduration10sThe wait before the first retry, doubling for each later one, unless the type sets queue.Backoffv0.2
QUEUE_BACKOFF_MAXduration10mCaps the doublingv0.2
QUEUE_POLLduration1sHow long an idle worker waits before looking for jobs againv0.2
QUEUE_TABLE, QUEUE_FAILED_TABLEstringjobs, failed_jobsThe database driver’s tables; pass the same names to queue.Migrationsv0.2
QUEUE_PREFIXstringAPP_NAME + :queue:Starts the Redis driver’s keys (Redis 5 or later). In a Redis Cluster, put a hash tag in it ({blog}:queue:). anetostest sets one per test appv0.2

Pub/sub

Read by pubsub.ForApp (or pubsub.LoadConfig) into pubsub.Config, and by the drivers. See Pub/sub listeners.

KeyTypeDefaultDescriptionSince
PUBSUB_DRIVERmemory | a driver’s name (redis, gcp)memoryThe broker; redis needs redis.PubSubDriver() and gcp needs gcppubsub.Driver() passed to pubsub.ForAppv0.2
PUBSUB_PREFIXstringnoneStarts topic names in the broker (Redis keys, Google IDs). Topics are shared with the other services using the broker, so leave it empty unless you need to separate them (or, in a Redis Cluster, need a hash tag: {events}:). anetostest sets one per test appv0.2
PUBSUB_REDIS_MAXLENint ≥ 01000000About how many messages each Redis stream keeps; 0 for no limitv0.2
PUBSUB_GCP_PROJECTstringnone (required with gcp)The Google Cloud project’s IDv0.2
PUBSUB_GCP_CREATEboolfalseCreate missing Google topics and subscriptions (development, the emulator)v0.2

Scheduler

Read by schedule.ForApp (or schedule.LoadConfig) into schedule.Config. See Scheduling.

KeyTypeDefaultDescriptionSince
SCHEDULE_TIMEZONEIANA time zone (Asia/Dhaka)APP_TIMEZONEThe time zone of schedules without .In(tz). Times that clock changes skip don’t run that day; times they repeat run twice (see Scheduling)v0.2

Mail

Read by mailer.ForApp (or mailer.LoadConfig) into mailer.Config, and by the drivers. See Send email.

KeyTypeDefaultDescriptionSince
MAIL_DRIVERlog | smtp | memory | a driver’s name (postmark)logHow emails are sent: log writes them to the app’s log (a warning in production), memory keeps them (tests; anetostest sets it); postmark needs postmark.Driver() passed to mailer.ForAppv0.2
MAIL_FROM_ADDRESSemail addressnoneThe sender of messages without one; sending fails without eitherv0.2
MAIL_FROM_NAMEstringAPP_NAMEThe sender’s namev0.2
MAIL_SMTP_URLURLsmtp://127.0.0.1:1025The SMTP server: smtp://user:pass@host:587 (STARTTLS, required unless the host is local) or smtps://…:465 (TLS); parameters tls=none, timeout (default 30s), local_name. See SMTP settingsv0.2
MAIL_POSTMARK_TOKENstringnone (required with postmark)The Postmark server’s API token (POSTMARK_API_TEST checks requests without sending)v0.2
MAIL_POSTMARK_STREAMstringoutboundThe Postmark message streamv0.2

AI

Read by ai.ForApp (or ai.LoadConfig) into ai.Config, and by the drivers. See Add AI to your app.

KeyTypeDefaultDescriptionSince
AI_PROVIDERanthropic | openai | openai-compatible | gemini | fake | another driver’s namenone (required)The provider that runs the models; its driver must be passed to ai.ForApp (fake is built in: it answers with scripted replies and never calls a model, a warning in production; anetostest sets it)v0.3
AI_MODELstringnone (required by the drivers)The model calls use unless they set ai.Model, by the provider’s name for itv0.3
AI_MAX_TOKENSint ≥ 14096The longest answer, in tokens, unless a call sets ai.MaxTokens; a longer one is cut offv0.3
AI_TIMEOUTduration > 010mHow long each request to the model may take, unless a call sets ai.Timeout; for a stream, including the time the reader’s loop takesv0.3
AI_EMBEDDING_PROVIDERa driver’s nameAI_PROVIDERThe provider of embeddings (ai.Embed, ai.Embeddings), when AI_PROVIDER’s has none (anthropic): openai, gemini, openai-compatible or fake; its driver is passed to ai.ForApp, and reads its own settings. anetostest clears itv0.3
AI_EMBEDDING_MODELstringnone; fake-embedding with the fakeThe embedding model, by the provider’s name for it (text-embedding-3-small, gemini-embedding-001); stored with each chunk, and searches use only its chunks. Required for embeddings, and with AI_EMBEDDING_PROVIDERv0.3
AI_QUEUE_TIMEOUTduration > 015mHow long a queued reply (conv.QueueReply) may take, all its requests and tool calls. Also how long the queue’s workers wait before taking back a job of any type whose worker died (the queue’s lease is its longest job timeout)v0.3
ANTHROPIC_API_KEYsecretnone (required with anthropic)The Anthropic API keyv0.3
ANTHROPIC_BASE_URLURLAnthropic’sAnother URL for the API (a proxy, a gateway)v0.3
OPENAI_API_KEYsecretnone (required with openai)The OpenAI API keyv0.3
OPENAI_BASE_URLURLOpenAI’sAnother URL for OpenAI’s API (a proxy, a gateway)v0.3
OPENAI_COMPATIBLE_URLURLnone (required with openai-compatible)The API URL of an OpenAI-compatible server, up to /v1: http://localhost:11434/v1 for Ollamav0.3
OPENAI_COMPATIBLE_KEYsecretnoneIts API key, if it needs one (then the URL must be https, or on this machine)v0.3
GEMINI_API_KEYsecretnone (required with gemini)The Gemini API key, from Google AI Studiov0.3
GEMINI_BASE_URLURLGoogle’sAnother URL for the Gemini APIv0.3

The OpenAI and Anthropic SDKs also read their own variables from the process environment (OPENAI_ORG_ID, OPENAI_PROJECT_ID, ANTHROPIC_AUTH_TOKEN…): the OpenAI driver uses them, the Anthropic and compatible drivers don’t.

Storage

Read by storage.ForApp (or storage.LoadConfig) into storage.Config for each disk, and by the drivers. The default disk reads STORAGE_*; a disk named in STORAGE_DISKS, say avatars, reads STORAGE_AVATARS_* (STORAGE_AVATARS_DRIVER, STORAGE_AVATARS_S3_BUCKET, …). See Store files.

KeyTypeDefaultDescriptionSince
STORAGE_DISKScomma-separated namesnoneMore disks: lower-case letters, digits and _, starting with a letterv0.2
STORAGE_DRIVERlocal | memory | a driver’s name (s3, gcs)localWhere the disk’s files are; s3 needs s3.Driver() passed to storage.ForApp, gcs gcs.Driver(). Named disks default to the default disk’sv0.2
STORAGE_ROOTdirectorystorage/app (storage/<name> for a named disk)The local driver’s directoryv0.2
STORAGE_URLURLnoneWhere the disk’s files are served: a CDN, a public bucket, or the route of the disk’s handler. Needed for URL, and for TemporaryURL on local disksv0.2
STORAGE_PUBLICboolfalseAnyone may read the files at STORAGE_URL, so URL works; otherwise only signed temporary URLs dov0.2
STORAGE_S3_BUCKETstringnone (required with s3)The bucketv0.2
STORAGE_S3_REGIONstringus-east-1The bucket’s region (auto for R2). Named disks take the default disk’s region, endpoint, keys and path style if they set none of themv0.2
STORAGE_S3_ENDPOINTURLAWSThe store’s URL, for S3-compatible stores (R2, MinIO, …). Named disks take the default disk’s region, endpoint, keys and path style if they set none of themv0.2
STORAGE_S3_ACCESS_KEY, STORAGE_S3_SECRET_KEYstringnoneThe credentials; without them, the AWS environment variables, shared credentials file or instance role. Named disks take the default disk’s region, endpoint, keys and path style if they set none of themv0.2
STORAGE_S3_PATH_STYLEboolfalseThe bucket in the URL’s path (MinIO). Named disks take the default disk’s region, endpoint, keys and path style if they set none of themv0.2
STORAGE_S3_PREFIXstring ending in /noneA prefix for the disk’s keys in the bucket (uploads/)v0.2
STORAGE_GCS_BUCKETstringnone (required with gcs)The Cloud Storage bucketv0.3
STORAGE_GCS_PREFIXstring ending in /noneA prefix for the disk’s objects in the bucket (uploads/)v0.3
STORAGE_GCS_CREDENTIALS_FILEpathnoneA service account key file (JSON); without it or STORAGE_GCS_CREDENTIALS, Application Default Credentials (the service’s account on Google Cloud, GOOGLE_APPLICATION_CREDENTIALS, gcloud). Named disks take the default disk’s credentials and signer if they set none of themv0.3
STORAGE_GCS_CREDENTIALSsecret (JSON)noneA service account key’s JSON, instead of a file. Both settings take service account keys only: other credentials go through GOOGLE_APPLICATION_CREDENTIALSv0.3
STORAGE_GCS_SIGNERemailthe credentials’ accountThe service account that signs temporary URLs through the IAM API when the credentials have no private key (an error with a key, which signs for its own account)v0.3
STORAGE_EMULATOR_HOSThost:portnoneRead by the Cloud Storage client: talk to an emulator (fake-gcs-server) without credentialsv0.3

Redis

Read by redis.Connect (module drivers/redis, also used by redis.CacheDriver(), redis.SessionDriver(), redis.QueueDriver() and redis.PubSubDriver()) into redis.Config.

KeyTypeDefaultDescriptionSince
REDIS_URLURLredis://127.0.0.1:6379/0The server, with its user, password and database: redis://:secret@cache.internal:6379/2; rediss:// for TLS. Options go in the query string (?dial_timeout=3s)v0.2

The server is pinged when the app boots, so the app and commands that boot it fail fast when Redis is unreachable.

Authentication

Read by auth.ForApp (or auth.LoadConfig) into auth.Config.

KeyTypeDefaultDescriptionSince
AUTH_LOGIN_URLpath/loginWhere Require sends guests asking for a pagev0.2
AUTH_HOME_URLpath/Where Guest sends signed-in usersv0.2
AUTH_REMEMBER_LIFETIMEduration720hHow long “remember me” lastsv0.2
AUTH_THROTTLEint5Login attempts allowed per minute for one login, or one account, from one IP address (cleared by a success)v0.2
AUTH_THROTTLE_IPint50Failed logins allowed per minute from one IP address (IPv6: its /64), whatever the loginv0.2
AUTH_RESET_TTLduration60mHow long a password-reset token worksv0.2
AUTH_VERIFY_TTLduration24hHow long an email-verification token worksv0.2

The remember-me cookie is HttpOnly, SameSite=Lax and Secure like the session cookie; a Secure one is named __Host-anetos_remember.

Social login

Read by social.ForApp and social.Configured, for each provider name (GOOGLE, GITHUB, or the upper-cased name given to social.OIDC, with - as _).

KeyTypeDefaultDescriptionSince
SOCIAL_<NAME>_CLIENT_IDstringemptyThe client ID of the app registered with the providerv0.2
SOCIAL_<NAME>_CLIENT_SECRETstringemptyIts client secretv0.2

Callback URLs are APP_URL followed by /auth/<name>/callback (social.WithCallbackPath changes the path).

Plugins

Each plugin’s settings start with its name in capitals (STRIPE_…), and are read by ext.Load into the plugin’s own settings struct. go run . plugins:env prints them with their defaults; anetos add adds them to .env.example. Missing or invalid ones stop the app from booting, with an error naming them. See Use plugins.

postmark

Read by the plugin of plugins/postmark (its mail transport reads MAIL_POSTMARK_*: Mail).

KeyTypeDefaultDescriptionSince
POSTMARK_WEBHOOK_USERstringemptyThe user name of the webhook’s basic auth, set in the webhook’s URL in Postmark (https://USER:PASSWORD@example.com/postmark/webhook). Without it or the password, the webhook refuses every request (401)v0.2
POSTMARK_WEBHOOK_PASSWORDsecretemptyThe webhook’s passwordv0.2