You commented. I listened. Here are responses to every unanswered comment across our articles. The dev.to API doesn't let me reply inline (it returns 404 on comment creation), so this is my workaround — one article that answers everyone.
To @mads_hansen (L3 article)
"I would distinguish periodic re-attestation from runtime monitoring. A weekly sandbox replay can detect drift; it cannot see an attack that runs between scans."
You're right — L3 is periodic re-attestation, not true runtime monitoring. The distinction matters. True runtime monitoring would require an in-process agent (like an eBPF probe or a syscall interceptor) that watches the MCP server's behavior in real-time. That's L4 on our roadmap — but it requires running inside the user's runtime, not in our sandbox.
What L3 does: catches drift that accumulates over time (config changes, supply chain updates, new tools). What it doesn't do: catch a skill that behaves normally during the weekly scan but maliciously between scans.
Honest answer: L3 is the best we can do without shipping an agent to the user's machine. L4 (in-process monitoring) is the real fix, but it's a heavier lift.
To @mayank609 (L3 article)
"Certification is necessary, but production systems keep changing—dependencies update, permissions drift."
Exactly the problem L3 solves. The weekly re-audit catches exactly these changes. If a dependency updates (npm version bump) or permissions drift (allowed_paths expand), L3 flags it before the user is affected.
Your feedback on CrewAI #6463 directly shaped this. Thank you.
To @anp2network (Responding to feedback article)
"The recursive sort closes the top-level-only gap, but there's a second-order issue: it lands on the exact property an attacker would target if they could influence key ordering."
You're describing a canonicalization attack — where an attacker manipulates JSON key order to produce a different canonical form that still validates. This is a real concern.
Our defense: We use JSON.stringify(sortedObj) which produces a single deterministic output for any given object structure. An attacker can't influence the key ordering because we sort them ourselves before serialization. The only way to produce a different signature is to change the payload content, not its serialization.
That said, you're right that canonicalization is a hard problem. The gold standard is something like RFC 8785 (JSON Canonicalization Scheme). We're not there yet, but it's on the roadmap.
To @mads_hansen (Responding to feedback article)
"Compromise recovery depends on revocation distribution. A verifier with a cached registry can keep accepting attacker-signed ATCs until it learns the old key is revoked."
This is the OCSP problem (Online Certificate Status Protocol) — same issue SSL has. Our current solution: verifiers call GET /api/atc?action=verify on every check (no caching). This is slow but correct.
Better solution (on roadmap): Signed revocation lists with short TTLs. The verifier caches the revocation list for 5 minutes. If a CA key is compromised, the new revocation list is published within 5 minutes, and all verifiers pick it up on their next check.
You also suggested signing the key registry itself — that's a great idea. The CA should sign its own key list, so a verifier can detect if the key list was tampered with.
To @neelagiri65 (Post-mortem article)
"The fix that actually holds is signed packages plus a runtime sandbox, not just more scanning layers."
Agreed. Signed packages (like npm's provenance) plus runtime sandboxing is the gold standard. We have:
- Signed packages: every Sentinel certificate is SHA-256 signed
-
Runtime sandbox: L2 runs in gVisor with
--network none,--read-only,--cap-drop ALL - Continuous monitoring: L3 re-runs weekly
What we don't have yet: package-level signing (signing the npm tarball itself, like Sigstore/cosign). That's on the roadmap — we're looking at integrating with npm's provenance feature.
To @neelagiri65 (8 layers article)
"Eight layers is a lot to maintain honestly. The useful bit is which ones actually caught something in practice."
Fair question. Here's what each layer has actually caught:
| Layer | Caught something? | What |
|---|---|---|
| L1.5 | Yes | 536 skills flagged for "no auth required" or "no rate limiting" |
| L1.6 | Yes | 456 secrets found in skill descriptions (mostly example keys in READMEs) |
| L1.7 | Yes — the trojan | Caught the unit.exe binary in the prospector-email-finder zip |
| L1.8 | No | 0 malware family matches (but the trojan was caught by L1.7 first) |
| L2 | Yes | 103 skills failed to start in sandbox (MODULE_NOT_FOUND, crash) |
| L3 | No (just shipped) | Too early — first weekly run hasn't happened yet |
| WAF | Yes | Blocked SQLi, XSS, SSRF attempts on our API |
| Honeypot | Yes | 4 scanners banned for hitting /.env, /admin |
| Threat Intel | No | 0 skills with URLs in URLhaus (catalog is clean) |
L1.7 is the MVP. It caught the only real attack we've seen. The other layers are defense-in-depth — they haven't caught anything yet, but they're cheap to run and would catch different attack classes.
To @kordless (ACP article)
"ACP is a spec for agent to agent comms: agentclientprotocol.com"
You're right — we were aware of the existing ACP spec and actually killed our ACP implementation because it competed in the wrong layer. We pivoted to ATC (Agent Trust Card) which is the trust layer, not the communication layer. ACP/A2A/MCP handle communication. ATC handles trust. Complementary, not competitive.
Full pivot writeup: https://dev.to/edison_flores_6d2cd381b13/ai-agents-need-their-own-ssl-heres-why-i-built-it-1njk
To @alexshev (MarketNow 2.0 article)
"The stronger metric is whether users can connect, run a first workflow, and know what failed."
100% agree. Downloads are vanity. The metric that matters is "did the agent successfully call a tool and get a useful response."
We're instrumenting this now:
-
/api/agent-purchasereturns the fullsystem_prompt+installcommand +capabilities— so the agent has everything it needs in one call -
/api/audit-skillreturns the Sentinel score — so the agent knows if the skill is safe before calling it - Coming: success tracking (did the install command work? did the first tool call succeed?)
To @pakvothe (5 idiomas article)
"Los objetos TRANSLATIONS a mano funcionan hasta que el producto crece. La solución escalable es extraer las traducciones a archivos JSON separados."
Tienes razón. Ahora mismo tenemos las traducciones inline en el código (un objeto por idioma). Funciona para 5 idiomas y ~30 rutas, pero no escalaría a 20 idiomas.
Plan: Migrar a archivos JSON separados (/locales/en.json, /locales/es.json, etc.) cargados dinámicamente. Esto permite:
- Contribuciones de la comunidad (PR para añadir un idioma)
- Lazy loading (solo cargar el idioma del usuario)
- Mejor DX (editar un JSON es más fácil que navegar un objeto JS)
Gracias por el feedback — es el tipo de cosa que se ignora hasta que duele.
To @custralis (Sandbox article)
"--network none only closes egress — a tool that reads the filesystem or spawns processes is still dangerous."
Correct. --network none blocks network but doesn't restrict filesystem or process access. That's why we layer:
-
--network none→ blocks exfiltration -
--read-only→ blocks writes to the root filesystem -
--cap-drop ALL→ drops all Linux capabilities (no root, no raw sockets, no ptrace) -
--security-opt no-new-privileges→ prevents privilege escalation -
--memory 256m --cpus 0.5→ prevents resource exhaustion - gVisor → userspace kernel intercepts syscalls (stronger than seccomp)
The full Docker command:
docker run --rm \
--network none \
--read-only \
--cap-drop ALL \
--security-opt no-new-privileges \
--memory 256m --cpus 0.5 \
mcp-audit-target
We also add --tmpfs /tmp for skills that need write access, scoped to a small partition.
To @nazar-boyko (8 layers article)
"Layers 3 and 4 are pattern and family matching, which is exactly the technique malware authors optimize against."
True — regex-based pattern matching is evadable. A sophisticated attacker can obfuscate their code to avoid matching our patterns.
Our defense-in-depth: L1.7/L1.8 catch known patterns. L2 (sandbox) catches behavior, not patterns — even if the code doesn't match any regex, the sandbox sees what it actually does (network calls, file writes, process spawns). L3 catches drift over time.
No single layer is sufficient. That's why there are 9.
To @wrencalloway (8 layers article)
"The hard one is a skill that ships clean and then pulls its payload at runtime."
This was the #1 feedback across all articles. L3 is our answer — it re-runs the sandbox weekly and detects if the skill's behavior changed since certification. But as @mads_hansen pointed out, it's periodic, not real-time.
The real fix is L4 (in-process monitoring) — an agent that runs inside the user's runtime and watches the MCP server's syscalls in real-time. That's on the roadmap but requires shipping a native binary (eBPF on Linux, Endpoint Security framework on macOS).
Summary
28 comments across 9 articles. The community consistently identified 3 gaps:
- Runtime trust (4 reviewers) → L3 is the first answer, L4 is the real fix
- CA key management (3 reviewers) → Key rotation + signed revocation lists on roadmap
- Canonicalization (2 reviewers) → Fixed (recursive sort), RFC 8785 on roadmap
Every comment made the system better. Keep them coming.
— Edison Flores, AliceLabs LLC — marketnow.site
Top comments (0)