Skip to content
Agentmart
Submit a tool

security-and-hardening

Hardens code against vulnerabilities (MeKnow-adapted, polyglot).

Skill by minhlucvan

IndexedApache-2.0
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/minhlucvan-security-and-hardening

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Hardens code against vulnerabilities (MeKnow-adapted, polyglot). Use when handling untrusted documents or webhook payloads, working with tenant isolation or server-side ACL in retrieve_kb, encrypting/decrypting provider credentials, the service JWT between backend and workers, or any answer-producing path. Use when building any feature that accepts untrusted data, manages tokens, or crosses a tenant boundary. Maps the OWASP Top 10 onto this repo's concrete controls (multi-tenant isolation + ACL-cohort cache keys, server-side ACL in retrieve_kb, Fernet credential encryption, HS256 service JWT, HMAC-signed inbound webhooks, citations-mandatory refusal, the compression invariant against KB prompt-injection).

Use cases: backend, data, security, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/security-and-hardening

What's inside

Skill name
security-and-hardening
Description
Hardens code against vulnerabilities (MeKnow-adapted, polyglot). Use when handling untrusted documents or webhook payloads, working with tenant isolation or server-side ACL in retrieve_kb, encrypting/decrypting provider credentials, the service JWT between backend and workers, or any answer-producing path. Use when building any feature that accepts untrusted data, manages tokens, or crosses a tenant boundary. Maps the OWASP Top 10 onto this repo's concrete controls (multi-tenant isolation + ACL-cohort cache keys, server-side ACL in retrieve_kb, Fernet credential encryption, HS256 service JWT, HMAC-signed inbound webhooks, citations-mandatory refusal, the compression invariant against KB prompt-injection).
License
Apache-2.0
Instructions
448 lines in SKILL.md · view on GitHub

Before installing

  • Instructions call the network

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Security and Hardening

## Overview

Security-first development practices for the Mezon Mentor Bot ("MeKnow")
multi-tenant RAG platform — the `backend`, the workers (`worker-ingest`,
`worker-retrieve`, `worker-task`, `worker-webhook`, …), and the shared `packages/`
(`rag-core`, `agent-core`, `arag-core`, `ingest-core`, `llm-transport`). Treat
every external input as hostile, every secret as sacred, every authorization check
as mandatory, and **every other tenant's data as off-limits**. Security isn't a
phase — it's a constraint on every line that touches a query, a cache key, KB
content, provider credentials, or the LLM/retrieval path.

Each project encodes its own concrete security controls as **invariants**. In an
mzspec-installed repo these live in `mzspec.config.json` under the `invariants`
array — read them first and map any new work onto them rather than inventing
parallel mechanisms. The table below is the **MeKnow reference set** (the example
this skill was extracted from); replace it with your project's `invariants` when
adapting the skill, and keep the methodology (OWASP-mapped, invariant-driven) intact.

## The MeKnow Security Invariants (reference example — do not break these in MeKnow)

| Invariant | What it defends | Where |
|---|---|---|
| **Multi-tenant by default** — `tenant_id` on every table, query, cache key, and log line; cross-tenant joins are bugs; cache keys include an ACL-cohort hash | Cross-tenant data leakage (the #1 risk) | every query path; cache layer |
| **ACL enforced server-side inside `retrieve_kb`** — caller identity inherited from the request, never trusted from the model | Broken access control; privilege confusion via the model | `retrieve_kb` in `rag-core`/`worker-retrieve` |
| **Provider credentials Fernet-encrypted**, decrypted only server-side | Secret exposure; blast radius if a worker host is compromised | `ingest_core.crypto` |
| **Service JWT (HS256) between backend and workers** | Spoofed inter-service calls | backend ↔ worker auth |
| **Inbound webhooks HMAC-signed and verified** before the payload is trusted | Spoofed events, forged ingests/triggers | `worker-webhook` |
| **Citations mandatory** — answer paths refuse rather than emit ungrounded claims (`filter` stage contains `refuse_if: no_citations`) | Ungrounded / fabricated output | `filter` stage; `agent-core` |
| **`temperature == 0`** on every `synthesize`, `cite`, `filter` stage | Non-determinism in grounded paths | policy stages |
| **Compression invariant** — raw KB chunks never leave a sub-agent; only `memo_schema_ref`-shaped objects cross stage boundaries | KB-content prompt-injection leaking across boundaries | sub-agent boundaries |
| **Versions are append-only** — `BotVersion`, `KBVersion`, golden sets, traces are new children, never in-place mutation | Tampering with the behavior/audit record | data model |
| **OpenAPI is the API contract** — portal types are generated, never hand-written | Drift between enforced contract and client | backend OpenAPI gen |

When you touch a subsystem, the invariant in that row is the control you must
preserve. The rest of this skill maps OWASP onto them.

## When to Use

- Building anything that accepts a request, webhook payload, or KB document content
- Working on the server-side ACL inside `retrieve_kb`, or any retrieval path
- Encrypting/decrypting or storing provider credentials (`ingest_core.crypto`)
- Issuing or verifying the service JWT between backend and workers
- Verifying inbound webhook HMAC signatures (`worker-webhook`)
- Ingesting documents (the untrusted KB → prompt-injection surface)
- Touching a query, cache key, or log line (the `tenant_id` surface)
- Handling any PII or credential data

## Process: Threat Model First

Controls bolted on without a threat model are guesses. Before hardening, spend
five minutes thinking like an attacker.

1. **Map the trust boundaries.** Where does untrusted data cross into the system?
   In MeKnow: **inbound webhook payloads**, **end-user questions** (which become the
   model prompt), **ingested KB documents** (which become retrieval context and can
   carry prompt-injection), provider API responses, and the **LLM's own output**
   (which is shown to users with citations). Every one is attack surface — and the
   **tenant boundary** sits across all of them.
2. **Name the assets.** What's worth stealing or breaking? **Another tenant's KB
   data and answers** (the crown jewels), provider credentials (Fernet-encrypted),
   the service-JWT signing secret, the Fernet key, the integrity of grounded answers
   (citations), and the append-only version record.
3. **Run STRIDE over each boundary** — a quick lens, not a ceremony:

| Threat | Ask | MeKnow mitigation |
|---|---|---|
| **S**poofing | Can someone forge a webhook or impersonate a worker? | Inbound webhook HMAC verify; service JWT (HS256) on backend↔worker calls |
| **T**ampering | Can data be altered in transit/at rest? | TLS; parameterized queries; append-only versions; Fernet AEAD on credentials |
| **R**epudiation | Can an action be denied later? | Append-only `BotVersion`/`KBVersion`/traces are an audit trail; tenant_id on every log line |
| **I**nformation disclosure | Can secrets or another tenant's data leak? | `tenant_id` + ACL-cohort cache keys; server-side ACL in `retrieve_kb`; Fernet at rest; compression invariant; never log secrets |
| **D**enial of service | Can it be overwhelmed? | p95 latency gate; bounded retrieval; request/document size caps; HTTP timeouts |
| **E**levation of privilege | Can a caller gain rights it shouldn't? | Server-side ACL with inherited caller identity; service-JWT scope; tenant scoping on every query |

4. **Write abuse cases next to use cases.** For each feature, ask "how would I
   misuse this?" — especially "can I read another tenant's data?" and "can a poisoned
   KB document make the model exfiltrate context?" — then make that your first test
   (`pytest` for Python; the gate scripts `tenant-isolation-test.sh` and
   `retrieve-kb-acl-test.sh` for the cross-cutting guarantees).

If you can't name the trust boundaries for a feature, you're not ready to secure
it. This is OWASP **A04: Insecure Design** — most breaches begin in design.

## The Three-Tier Boundary System

### Always Do (No Exceptions)

- **Scope every query, cache key, and log line by `tenant_id`.** Cross-tenant joins are bugs.
- **Enforce ACL server-side inside `retrieve_kb`** using the caller identity inherited from the request — never read it from model output or tool arguments.
- **Include the ACL-cohort hash in cache keys** so two callers with different KB permissions never share a cached answer.
- **Parameterize all queries** — never concatenate input into SQL.
- **Verify inbound webhook HMAC signatures** before acting on a payload.
- **Verify the service JWT** on backend↔worker calls; sign with the HS256 secret only server-side.
- **Encrypt provider credentials with Fernet** at rest (`ingest_core.crypto`); decrypt only server-side, only when needed.
- **Keep `refuse_if: no_citations`** in the `filter` stage; keep `temperature == 0` on synthesize/cite/filter.
- **Keep the compression invariant** — raw KB chunks stay inside the sub-agent; only `memo_schema_ref`-shaped objects cross boundaries.
- **Use TLS** for all provider and inter-service communication.
- **Fail fast** when a required secret (Fernet key, service-JWT secret, DB URL) is missing.
- **Run the dependency audit** (`uv pip`/`pip-audit`, `pnpm audit`, `govulncheck` for Go modules) before a release; keep lockfiles committed.

### Ask First (Requires Human Approval)

- Adding or changing authentication/authorization logic (service JWT or the `retrieve_kb` ACL)
- Changing the credential-encryption scheme (Fernet) or key handling
- Adding a new provider/connector or changing webhook signature verification
- Loosening tenant scoping, an ACL check, or CORS
- Changing cache-key composition (especially dropping `tenant_id` or the ACL-cohort hash)
- Relaxing `refuse_if: no_citations`, raising `temperature` on a grounded stage, or weakening the compression invariant
- Changing what gets logged near tokens, keys, credentials, or KB content

### Never Do

- **Never run a query, build a cache key, or write a log line without `tenant_id`.**
- **Never trust the caller identity (or ACL decision) from model output or tool args** — enforce it server-side.
- **Never let raw KB chunks cross a sub-agent boundary** (compression invariant).
- **Never commit secrets** — the Fernet key, service-JWT secret, provider credentials.
- **Never log sensitive data** — keys, decrypted credentials, service JWTs, or another tenant's KB content.
- **Never emit an answer with no citations** — refuse instead.

From minhlucvan/emdesign, Apache-2.0.

More from minhlucvan/emdesign

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Jun 26, 2026 (4 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from minhlucvan

Cite this page

security-and-hardening skill. Agent Mart. https://agentmart.dev/skills/minhlucvan-security-and-hardening (last updated 2026-10-24)