Conversation
…lities - Write credentials to ~/.aikido-creds.json (chmod 600) instead of passing as env vars in .claude.json, preventing accidental exposure through environment dumps - Add shellEscape() helper and apply it to all paths in shell commands, preventing injection attacks when workspace/file paths contain special characters Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
insuT0ver
added a commit
that referenced
this pull request
Jun 29, 2026
* feat: verwijder Sparky vLLM-integratie volledig (#4) Verwijdert alle Sparky-gerelateerde code en configuratie: - huddle.ps1: Start-SparkyProxy functie, variabelen en --add-host flag - .ai/opencode/opencode.json: sparky-provider en modelregistratie - .ai/opencode/AGENTS.md: alle Sparky-instructies - .ai/README.md: Sparky-vermeldingen Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: verbeter gateway block response met rijke JSON-foutinfo (#2) De proxy geeft nu een gestructureerde JSON-response bij geblokkeerde requests: - error: REQUEST_BLOCKED_BY_HUDDLE (machine-leesbaar) - blockedEndpoint, reason, actionRequired - devcontainerId voor traceerbaarheid - huddlePortal URL voor directe navigatie - x-huddle-blocked header voor snelle detectie door clients send403, rejectSocket en MITM-padblocking allemaal bijgewerkt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: voeg resource caps toe voor devcontainers (#3) Nieuwe memory- en CPU-limieten kunnen worden ingesteld bij het starten van devcontainers of als globale standaard in de instellingen. - docker.ts: parseMemoryBytes/parseCpuQuota helpers; StartParams.memory/cpus; HostConfig.Memory/CpuQuota/CpuPeriod worden doorgegeven aan Docker - api.ts: POST /api/docker/start accepteert memory en cpus; GET/POST /api/settings beheert defaultMemory en defaultCpus - api.service.ts: HuddleSettings bijgewerkt naar defaultMemory/defaultCpus - settings.component.ts: UI voor globale resource limieten Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: vervang hardcoded AI-mounts door generieke foldermappings (#5 #6) Verwijdert de vaste Claude/Codex/OpenCode provider-mount logica en vervangt die door een configureerbare folder_mappings tabel. Operators kunnen via de Instellingen-pagina bindmounts of named volumes toevoegen, bewerken en verwijderen. Verwijdert ook de hardcoded AI_CONFIG_DIR en de COPY .ai/… stappen uit de Dockerfile. De .ai-map wordt niet meer ingebakken in het image maar als gewone runtime bindmount aangeboden (standaard host_path = /.ai). De .ai-map is uit git-tracking verwijderd. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: voeg Docker host port approval flow toe met poortbeheer UI (#7) Containers die een host-poort willen binden worden onderschept door de socket-proxy. Niet-goedgekeurde poorten worden geblokkeerd met HTTP 403. Operators keuren poorten goed via de Docker-tab op de containerdetailpagina of via de Docker Access-pagina. Backend: GET/POST/DELETE /api/containers/:name/ports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * clean up * docs: herschrijf README met uitgebreide getting started en uitleg - Vervang PS1-script door npm run build/start/install commando's - Voeg sectie toe voor containers openen in JetBrains en VS Code - Leg AI-configuratie (.ai/) uit met Windows→container padmapping - Vervang Freshdesk-voorbeeld door Aikido Security extensie - Voeg firewall-beheer sectie toe Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: standaard resource limieten 8g/2cpu, hernoem Audit Logs naar Network Logs, fix rogue-status voor gestopte containers - Nieuwe devcontainers krijgen standaard 8 GB RAM en 2 CPU tenzij de operator een andere waarde heeft ingesteld - "Audit Logs" hernoemd naar "Network Logs" in sidebar, paginatitel en container-detail - Dashboard markeert gestopte containers nu correct als "Stopped" i.p.v. "Rogue" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
12 tasks
insuT0ver
added a commit
that referenced
this pull request
Jul 16, 2026
* feat(gateway): security-hardening (findings #1–#15, excl. Aikido) Squashed hardening work on top of main (operator-auth + source-IP-gate removal already landed via #47). Internal review/design docs and the Aikido extension changes (findings #6/#14) intentionally left out of this branch. - #1/#2 socket-proxy HostConfig allowlist: reject VolumesFrom, DeviceCgroupRules, DeviceRequests and the device family (host/daemon takeover, raw-disk access). - #3 CONNECT hostname canonicalization + COLLATE NOCASE so casing can't bypass an exact deny carved out of a wildcard allow. - #7 path-allowlist normalization (fail-closed on ../ and ..%2f, segment boundaries), normalized path forwarded upstream. - #8 named-volume ownership check (huddle.parent) + GET /volumes filtered. - #9 folder-mapping column allowlist kills the JSON-key SQL injection; route returns 400/404 instead of 500. - #11 extension-bundle SHA-256 integrity check before extraction (allowlist). - #12 token placeholder bound to the requesting container (timing-safe) + TTL; no shared 'unknown' bucket; redacted from the audit body. - #13 PTY multi-attach logs attach:owner vs attach:join(N) so a join is never silent (regression test added). - #15 IDE credential channel: VS Code Machine settings (workspace trust, no auto-tasks, no local terminal, null credential env) + a container-side guard that strips the forwarded git credential.helper from /etc/gitconfig and ~/.gitconfig, tears down the forwarded GPG/SSH/askpass sockets, and re-applies on inotify events (fallback poll). JetBrains gets the shared env/socket scrub. Verified live: git push and `git credential fill` no longer obtain host creds. - e2e: authenticate with HUDDLE_OPERATOR_TOKEN; split devcontainer→API into proxy path (403) and direct path (401); targeted pre-flight on auth misconfig. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(gateway): address Aikido review on POST /api/rules Two Aikido findings on the finding-3 domain handling: - non-string `domain` (truthy but not a string) passed the truthiness check and then threw on .toLowerCase() → 500. Require typeof === 'string' → clean 400. - storing the domain lowercased mutated the value clients get back ("may break clients expecting original casing"). It was redundant anyway: matching is already case-insensitive (COLLATE NOCASE in db.ts + canonicalizeHost/matchDomain). Store the domain as provided; the requested-row cleanup DELETE gets COLLATE NOCASE so it still matches the lowercase requested rows the proxy creates. Finding #3 stays closed; echo-back to clients is preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(test): correct finding-3 e2e expectation for HTTPS CONNECT deny The finding-3 casing test expected a 403 from `curl https://gist.github.com`, but a host-level HTTPS deny refuses the CONNECT tunnel (rejectSocket → 403 on the CONNECT response). curl then reports http_code '000' — the 403 lives in http_connect_code, not http_code (unlike the plain-HTTP deny path, which does surface 403). So the request came back '000', not '403', and e2e failed. Assert '000' for both the exact and the capitalized host: a refused CONNECT is the correct, deterministic signal that the deny holds (no upstream egress needed). If casing bypassed the deny, the host would match the wildcard allow and the CONNECT would be accepted — not '000'. Path-mode 403 assertions (finding 7) are unchanged: those keep the tunnel open and return 403 inside the MITM'd session. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
TijsVK
added a commit
to TijsVK/huddle
that referenced
this pull request
Jul 18, 2026
…hz plugin
Adversarial review found the socket-proxy filter (dind-filter.ts) bypassable two
ways, both verified live:
1. the devcontainer mounted the dir holding BOTH the filter's docker.sock AND
the raw inner.sock — `curl --unix-socket inner.sock` skipped the filter.
2. even after splitting them, a nested container could symlink a shared
workspace path to the sidecar's socket dir and bind through it; dockerd
follows symlink bind sources, so a lexical bind guard can't stop it.
Root cause: putting a filter IN FRONT of an unfiltered daemon socket always
leaves that socket reachable. Fix: enforce the guard IN the daemon via
`--authorization-plugin=huddle-authz` (gateway/src/dind-authz.ts). dockerd calls
the plugin before every request on its single socket, so there is no unfiltered
path to reach (findings infosupport#1/infosupport#2 gone) and dockerd handles stream/hijack/chunk
framing natively (the old half-open/grpc/buffering complexity — findings infosupport#4/infosupport#5/infosupport#6
— dissolves).
Topology: sidecar dockerd listens on docker.sock (mounted into the devcontainer);
the gateway serves huddle-authz.sock, mounted into the sidecar at
/run/docker/plugins. No inner.sock. Under authz all binds are safe (docker.sock is
authz-guarded), so the DinD bind guard is dropped — Ryuk / docker-outside-of-
docker work.
Also closes review findings infosupport#3 (MaskedPaths/ReadonlyPaths unmask — deny when the
critical /proc/kcore mask or /proc/sysrq-trigger read-only path is removed; the
CLI sends these populated by default, so only an unmask is refused), infosupport#7
(privileged exec-create), infosupport#8 (any non-default seccomp/apparmor, not just literal
unconfined). validateDindEscape simplified to the kernel/device policy; the pure
host-config-policy.ts is reused by the plugin. The compat harness (lib.sh) now
runs the real plugin via authz-runner.mjs.
Verified live: no inner.sock; raw privileged create over docker.sock → 403;
symlink-bind bypass closed; privileged/device/exec denied; MaskedPaths unmask
denied; compose/buildx/exec/host-path-binds/Ryuk all work. 239 unit tests green
(dind-authz.test.ts replaces dind-filter.test.ts).
TijsVK
added a commit
to TijsVK/huddle
that referenced
this pull request
Jul 18, 2026
…ty mode has no bindable host path under the allowlist)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.