anvilsign in

collin/anvil

1# anvil configuration. Copy to `anvil.toml` and edit. All fields are optional;
2# omitted fields fall back to the defaults shown here.
3
4# Root directory for all server state (database + repositories).
5data_dir = "data"
6
7[http]
8listen = "127.0.0.1:3000"
9base_url = "http://localhost:3000"
10# Memory budget (MiB) for the cache of syntax-highlighted file views.
11# Highlighting large files is CPU-heavy, so repeat views are served from this
12# cache. Set to 0 to disable it entirely on RAM-constrained hosts.
13highlight_cache_mb = 16
14# Maximum size (MiB) of a single uploaded attachment (e.g. an image pasted
15# into the web file editor). Larger uploads are rejected.
16attachment_max_mb = 16
17# Per-repository cap (MiB) on total stored attachments. An upload that would
18# exceed it is rejected; re-uploading existing (deduped) content is free.
19# 0 means unlimited.
20attachment_quota_mb = 0
21
22# Single sign-on against an OpenID Connect provider (see docs/oidc.md).
23# Off unless `issuer` is set; password sign-in keeps working either way.
24[oidc]
25# e.g. "https://login.richardscollin.com", or "https://login.localhost" for a
26# provider running locally. Empty disables single sign-on entirely.
27issuer = ""
28# Client id registered at the provider.
29client_id = "anvil"
30# Client secret. Prefer the ANVIL_OIDC_CLIENT_SECRET environment variable —
31# config files get committed, this must not. Empty for a public client.
32client_secret = ""
33# Defaults to base_url + "/-/oidc/callback". Must match the URI registered at
34# the provider exactly; there are no wildcards.
35redirect_uri = ""
36# Sign-in button text, after "Sign in with ". Defaults to the issuer's host.
37label = ""
38# Whether signing out of anvil also ends the provider's session. Needs a
39# post-logout URI registered for this client to come back here afterwards.
40sso_logout = true
41
42[ssh]
43enabled = false
44# Internal bind address. Under Docker, set host = "0.0.0.0" and forward the port.
45listen = "127.0.0.1:2222"
46# What to show users in SSH clone URLs. Set clone_port to the externally
47# forwarded port if it differs from the internal bind (e.g. Docker -p 2200:2222).
48clone_host = "localhost"
49clone_port = 2222
50clone_user = "git"
51
52[ci]
53# Job sandbox. Containers always run with no Docker socket, no mounts, all
54# capabilities dropped, and no-new-privileges; these knobs bound resources
55# (0 = unlimited). See docs/untrusted-mode.md for the threat model.
56# Images a pipeline may use: empty allows any; a tagless entry ("rust") allows
57# every tag of that image; a tagged one ("alpine:3.20") exactly itself.
58allowed_images = []
59memory_mb = 2048
60cpus = 2.0
61pids_limit = 512
62# Wall-clock limit per job, after which the container is killed.
63timeout_secs = 1800
64# Whether jobs get network access (most builds need it to fetch dependencies).
65network = true
66# User inside the job container, e.g. "1000:1000". Empty keeps the image default.
67run_as = ""
68# Image for a pipeline that omits `image:`. This is anvil's own runner, shared
69# with agent sessions and built by deploy/runner/build.sh — it carries tmux,
70# git, fish and Claude Code. It is a LOCAL image with no registry behind it, so
71# anvil falls back to the local copy when the pull fails. Always allowed,
72# whatever allowed_images says.
73default_image = "anvil-runner:latest"
74
75[agent]
76# Agent sessions: a container per session running tmux plus an agent CLI
77# against one repository, attachable from a terminal in the browser.
78#
79# OFF by default, and deliberately so. CI runs code the pusher wrote; an agent
80# session runs a model that reads repository content, issue text and TODO items
81# as instructions, with network access it cannot do without. Prompt injection in
82# a README is therefore a code-execution path. See docs/untrusted-mode.md before
83# turning this on, and keep it to repositories you trust.
84enabled = false
85# Same image as [ci] default_image above.
86image = "anvil-runner:latest"
87# Directory holding the agent CLI's credentials (a ~/.claude for Claude Code).
88# Its contents are uploaded into each session container as a tar — never bind
89# mounted, so the container still cannot reach anvil's data directory. Empty
90# starts sessions unauthenticated.
91credentials_dir = ""
92# Session sandbox. Same shape as [ci]: all capabilities dropped, no socket, no
93# mounts. Memory defaults higher than CI's because Claude Code asks for 4 GB.
94memory_mb = 4096
95cpus = 2.0
96pids_limit = 1024
97# Reap a session after this long with no viewer attached AND no output. A
98# session someone is watching is never idle, however quiet the agent is.
99idle_timeout_secs = 3600
100# Hard cap regardless of activity.
101max_lifetime_secs = 86400
102# How many sessions may run at once across the instance. Each holds a container
103# open, so this is the real resource bound.
104max_concurrent = 4
105
106# Artifact caps (MiB, 0 = unlimited): one artifact / one run's total / the
107# rolling per-repo budget. Over the repo budget, the oldest commits' artifacts
108# are deleted after each run (branch tips pinned). See docs/ci-artifacts.md.
109artifact_max_mb = 256
110artifact_run_max_mb = 512
111artifact_quota_mb = 4096
112
113# Continuous deployment: on a green run of deploy_branch in the ONE repo named
114# by deploy_repo, POST to deploy_webhook with the X-Anvil-Deploy-Secret header.
115# Empty deploy_repo/deploy_webhook disables deploys entirely.
116deploy_repo = ""
117deploy_branch = "main"
118deploy_webhook = ""
119deploy_secret = ""