Commit graph

11 commits

Author SHA1 Message Date
7aaee37ac8 Fix git-wrapper: preserve argv[0] for multi-call dispatch, tighten security
- exec -a "$0" so git.real sees the correct argv[0] (e.g. git-upload-pack)
  and dispatches correctly; without this SSH clone was broken
- Check only $1 for "merge-file" instead of scanning all args, preventing
  accidental ifcmerge invocation from commit messages or other arg positions
- Use absolute path /usr/local/bin/ifcmerge to prevent PATH hijacking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:17:55 +01:00
b23b210f76 Document git-wrapper for ifcmerge: Forgejo uses git merge-file not merge-tree 2026-05-17 23:37:14 +01:00
b3e37c512a Fix query panel visibility and meta panel type counts
- Add /query proxy rule to nginx config (was missing, caused 404)
- Fix populateMetaPanel: call groupData.get() instead of reading empty
  groupData.map, and use ids.size (Set) not ids.length
- Update CLAUDE.md check #17 to reflect type counts now working

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 21:02:54 +01:00
bcf9d58470 service: fix preview pipeline for local Forgejo deployment
- auth.py: catch OSError (not just FileNotFoundError) so ProtectHome=yes
  doesn't crash token lookup — returns None and falls back to anonymous
- git.py: wipe partial bare-clone dir before HTTP fallback so git can retry
  after HTTPS fails (port 443 not available on local HTTP-only Forgejo)
- pyproject.toml: add python-multipart to service deps (FastAPI form data)
- ifcurl-api.service: fix ExecStart path (/opt/ifcurl), set allowed-hosts
  to localhost, add MPLCONFIGDIR to silence matplotlib cache warning
- ifcurl-render.service: fix ExecStart path, add CacheDirectory + MPLCONFIGDIR
- nginx-ifcurl.conf: new file tracking the nginx reverse-proxy config;
  listen on [::]:80 so IPv6 loopback requests reach the Forgejo proxy block

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 23:10:35 +01:00
6b6e47ef54 Split service into ifcurl-api + ifcurl-render for RCE isolation
render_service.py: new FastAPI app with /render, /select, /render_diff
endpoints that wrap run_sandboxed — listens on a Unix domain socket.

service.py: imports the three pipeline functions from render_service.py;
delegates to render service via httpx when IFCURL_RENDER_SOCKET is set,
falls back to direct run_sandboxed when unset (single-service mode).

__main__.py: add 'render-service' subcommand (--socket PATH).

pyproject.toml: add httpx to service optional deps.

ifcurl-api.service: renamed from ifcurl-preview.service; sets
IFCURL_RENDER_SOCKET, adds AF_UNIX to RestrictAddressFamilies.

ifcurl-render.service: new hardened unit — AF_UNIX only, ~execve
~execveat blocked, no credentials, separate ifcurl-render user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 10:00:33 +01:00
fef6c16946 ifcurl-preview.service: correct misleading execve comment
execve is actually permitted — it arrives via @default which is included in
@system-service.  The main service needs it for GitPython's git CLI calls.
Blocking execve only in render subprocesses would require per-process seccomp,
which is not worth the complexity for this threat model.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 08:30:41 +01:00
8e474f2629 gitconfig-ifcmerge: use --prioritise-local correctly per merge direction
ifcmerge defaults to preserving remote IDs; --prioritise-local preserves local
IDs instead.  For Forgejo merge commits, %A is main (local) so ifcmerge_ours
(--prioritise-local) is the right driver — main's IDs are preserved and the
PR branch is renumbered.  For developer rebases from main, %B is main (remote)
so the plain ifcmerge driver (no flag) preserves main's IDs by default.

Update /etc/gitattributes to use ifcmerge_ours for server-side merges, and
update README with a direction table clarifying which driver to use when.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 07:41:49 +01:00
275e74cce8 ifcurl-preview.service: fix cache path for non-root service user
Use CacheDirectory=ifcurl (systemd creates /var/cache/ifcurl owned by the
service user) and XDG_CACHE_HOME=/var/cache so platformdirs resolves to
that path.  Remove the /root/.cache/ifcurl ReadWritePaths entry which was
inaccessible to the unprivileged ifcurl user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 21:48:58 +01:00
df92114cda ifcurl-preview.service: systemd sandbox hardening
Add sandboxing directives to limit blast radius from a compromised render
subprocess:
- NoNewPrivileges + RestrictSUIDSGID: no privilege escalation
- ProtectSystem=strict + ProtectHome: Forgejo data tree is unwritable
- PrivateTmp: isolated /tmp
- RestrictAddressFamilies=AF_INET AF_INET6: no Unix socket access to Forgejo
- SystemCallFilter=@system-service @process @files @io-event @network-io:
  allows fork/clone (needed by ifcopenshell geom workers) but excludes
  execve/execveat so an attacker cannot exec a shell
- RestrictNamespaces, LockPersonality, ProtectKernelTunables, etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 21:47:48 +01:00
27883e468e forgejo: document ifcmerge mergeability — bare repo gitattributes finding
Investigation confirmed: Forgejo's git merge-tree --write-tree (git ≥2.38)
does invoke configured merge drivers for .ifc files.

Key finding: bare repositories do NOT read committed .gitattributes — the
merge driver is silently skipped without a system-wide core.attributesFile.

Changes:
- server-config/gitattributes: new file to deploy at /etc/gitattributes,
  containing "*.ifc merge=ifcmerge"
- server-config/gitconfig-ifcmerge: adds [core] attributesFile = /etc/gitattributes
  and explains the bare-repo constraint
- forgejo/README.md: rewrites ifcmerge section with investigation findings,
  deployment steps, and distinction between server-side vs client-side setup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 09:27:56 +01:00
e824f9fd0e forgejo: systemd unit, ifcmerge driver docs; fix stale proxy mention
- forgejo/server-config/ifcurl-preview.service: systemd unit for the preview
  service with dedicated user, EnvironmentFile for cache config, and
  --allowed-hosts in ExecStart
- forgejo/server-config/gitconfig-ifcmerge: registers two [merge] driver
  variants (ifcmerge and ifcmerge_ours) for the asymmetric .ifc merge case
- forgejo/README.md: systemd deployment section (manual + service), ifcmerge
  section covering Perl script install, driver registration, per-repo
  gitattributes, and merge-direction constraint (merge-commit preserves main's IDs)
- README.md: remove stale "IFC file proxy" description; update quick-summary
  to show systemd install path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 09:17:32 +01:00