Access from other computers
By default the Foundry answers only on the Mac it runs on. Colleagues can reach it from their own
computers when you set three things in Settings → Network (or in config.yaml):
server:
listen: 127.0.0.1 # 127.0.0.1 (default), ::1, 0.0.0.0 or ::
allowed_hosts: [mymac.local] # names people type; a port is optional
allow_insecure_http: false # true: also accept plain HTTP from other computers
listenis the address the server binds.0.0.0.0and::answer on every network; the other two only on this Mac. Only these four values are allowed. A change needs a restart.allowed_hostsreplaces the old fixed localhost check.localhost,127.0.0.1and[::1](with the server port) always work. Any otherHostheader must be listed, else the answer is403 forbidden host. A change applies at once.allow_insecure_httpis off by default. A change applies at once.
The safe way: HTTPS through Caddy on the Mac. The Foundry has no TLS of its own. A proxy on the
same Mac does the HTTPS and talks to the Foundry on 127.0.0.1.
- Keep
listen: 127.0.0.1. Add the Mac's name to the allowed host names. Use the local host name from System Settings → General → Sharing, for examplemymac.local. Colleagues must be able to resolve that name (macOS does it on the same network; other systems may need a DNS or hosts entry). - Install Caddy:
brew install caddy. - Write the Caddyfile. Homebrew's service reads
$(brew --prefix)/etc/Caddyfile:mymac.local { tls internal reverse_proxy 127.0.0.1:4777 } - Start it:
brew services start caddy(it starts again at login). After a change:brew services restart caddy. To try it once in a terminal:caddy run --config <file>. - Trust the certificate on the Mac itself:
caddy trust. - Give your colleagues Caddy's root certificate,
root.crt. Caddy keeps it in its data folder, by default~/Library/Application Support/Caddy/pki/authorities/local/root.crtwhen it runs as your user. Check that the file exists on your Mac. On macOS, open it with Keychain Access, add it to System, then set it to Always Trust. On Windows, import it into Trusted Root Certification Authorities. Firefox has its own certificate store. - Check it:
curl --cacert root.crt -sI https://mymac.local/shows200andstrict-transport-security.curl -s -H 'Host: mymac.local' http://127.0.0.1:4777/answersHTTPS required.
What any proxy must do.
- Run on the same Mac and connect to
127.0.0.1:<port>. The Foundry believes forwarded headers only from a connection that comes from this Mac. - Pass the
Hostheader unchanged, with its port. - Set
X-Forwarded-Protoitself from the real connection (overwrite what the client sent, never pass it on) and sendX-Forwarded-For. - Not buffer responses (the run log is a stream).
Caddy does all of this by default. For nginx use proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off; ($host drops the port, so use $http_host). A proxy that rewrites Host to
127.0.0.1:4777 and sends no forwarded headers makes remote requests look local; do not use one.
Plain HTTP on a trusted network. Set listen: 0.0.0.0, add the Mac's name or address to the
allowed host names and switch on allow_insecure_http. Warning: passwords and session cookies
then cross the network unencrypted. Use it only on a network you trust.
What the server does.
- Over HTTPS (through the proxy) the session cookie is
Secureand responses carryStrict-Transport-Security(one year). - Every response carries a strict
Content-Security-Policy(only this server's own scripts and styles) andX-Content-Type-Options: nosniff. - A change (POST, PUT, DELETE) with an
Originheader must come from exactly the address you used: same scheme, name and port. - Requests from other computers are refused with
HTTPS requiredunless they come through the proxy over HTTPS, orallow_insecure_httpis on. - The server does not start on
0.0.0.0or::until an admin account exists. - The first admin can only be created on the Mac itself, not through the proxy.
- Settings cannot be saved if the change would lock out the browser that saves it (its host name
removed, or a
listenvalue that does not cover the address it is connected to). - Sign-in and set-password also wait per client address (from the 5th wrong try, up to 60 seconds; see "Wrong passwords" in Settings and safety) and run at most 16 password checks at the same time; an e-mail longer than 254 characters is a wrong sign-in.
Restart after changing the address: stop and start scf ui, or run scf service install again.
Do not mix HTTPS and plain HTTP on one host name: HSTS makes browsers refuse HTTP for that name for a year.
A user account can only use Runs and the calls in "Roles and permissions" above, but a run can
still run commands on this Mac, so only give accounts to people you trust. Links
in Slack and notifications still point at http://localhost:<port>.
Stored credentials. A token or an ssh key can be stored through the API
(POST /api/credentials); there is no UI page yet, and runs do not use them yet. They are kept in
credentials.json in the data folder (mode 0600), encrypted with AES-256-GCM. The key is not in
the data folder: it is in the macOS Keychain, as an item of the service
claude-factory-credential-key. Only macOS is supported. The token or deploy key of a repository is stored here
too, as repo:<repository id>; your own names must not start with repo:. The public key of a deploy key
is not a secret: /api/repos always shows it in full, even when a stored secret is part of it (the rest of
the answer is hidden as before).
- What the API shows. Only type, name, created, last used and the fingerprint, never the
secret. A token must be 8 to 4096 printable ASCII characters on one line. To check a fingerprint:
printf %s "$TOKEN" | shasum -a 256, the first 16 digits. - Redaction. A stored secret is replaced by
[redacted]in step output, logs, transcripts, errors and API answers. Limits: text written before a credential was saved stays on disk (the API hides it), the task text and other encodings (such as base64 ofuser:token) are not matched. If credentials exist and the Keychain is locked or the key is gone, runs fail before they start and the API shows nothing until that is fixed. - Deleting. Deleting a credential or a user (
scf user delete) replaces the key, so older copies ofcredentials.jsonare useless.scf credential rotate-keydoes the same on demand. - Who can read the key. Anyone who runs commands as your macOS user, flow steps included. The encryption protects copies of the data folder: backups, sync, another user.
Global settings are stored in ~/.spaghetti-code-foundry/config.yaml; runs in ~/.spaghetti-code-foundry/runs/.