BLA
BLA는 오픈소스 Blue Defense MCP와 CLI로, 소프트웨어 자산을 자동 AI 리버스 엔지니어링으로부터 보호합니다
DNS-01 검증·와일드카드 인증서·CNAME 위임·배포 훅·자동 갱신 설명과 로컬 LLM 기반 문서 도우미 제공
Explainers on DNS-01 validation, wildcard certificates, CNAME delegation, deploy hooks and automated renewal, plus a documentation assistant that runs a local LLM over CertMate's docs. No credentials,
보안Python · AstroGitHub @fabriziosalmi온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Documentation assistant for CertMate
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Documentation assistant for CertMate
(source).
Embedded local LLM (LM Studio by default) + retrieval over CertMate's
documentation. Ask how a feature works, how to configure a DNS provider, what
DNS-01 or a deploy hook actually does.
Unlike a generic chat, it is instructed to search the CertMate documentation
before answering and to cite the file each claim came from. That is a prompt
rule, not a guarantee: nothing yet checks that an answer stays inside the
retrieved text, or that the agent declines when retrieval finds nothing.README 전문 보기 ↗Documentation assistant for CertMate (source).
Embedded local LLM (LM Studio by default) + retrieval over CertMate's documentation. Ask how a feature works, how to configure a DNS provider, what DNS-01 or a deploy hook actually does.
Unlike a generic chat, it is instructed to search the CertMate documentation before answering and to cite the file each claim came from. That is a prompt rule, not a guarantee: nothing yet checks that an answer stays inside the retrieved text, or that the agent declines when retrieval finds nothing.
It does not connect to a running CertMate instance and holds no
credentials. For driving a live instance from an assistant, CertMate ships
its own MCP server (mcp/ in the CertMate repository), maintained where the
API is maintained. This agent used to map that API too; a second mapping could
only drift out of date, and it had — so it was removed in 0.2.0 along with the
credential it needed to be useful.
Part of the CertMate ecosystem:
Enterprise / high-scale — multi-tenant, mTLS, white-label and NIS2-aligned deployments are available through CertMate-ng (source-available, BSL 1.1, EU-built). Contact [email protected].
user ──► widget (vanilla web component)
│ SSE
▼
FastAPI agent ──► LM Studio (chat + embeddings, OpenAI-compatible)
│
└─► local docs index (gzipped JSON, no network at query time)
docs_search, executed inline against the local index.cp .env.example .env
# point LMSTUDIO_URL at your LM Studio server. There is no CertMate URL or
# token to set: config.py has no such setting and the agent never calls one.
uv pip install -e . # or: pip install -e .
python -m agent.main
Open http://127.0.0.1:8765/widget/ for the standalone test page.
Embed in CertMate or any page:
<script type="module" src="http://127.0.0.1:8765/widget/certmate-agent.js"></script>
<link rel="stylesheet" href="http://127.0.0.1:8765/widget/certmate-agent.css">
<certmate-agent endpoint="http://127.0.0.1:8765"></certmate-agent>
| Method | Path | What |
|---|---|---|
| GET | /health | agent + LM Studio health |
| GET | /models | check the configured chat/embed models are loaded |
| POST | /chat | SSE stream — body {message, history?} |
Configured by default with google/gemma-4-e2b (chat) and
text-embedding-embeddinggemma-300m (embeddings).
Gemma's small variants are "thinking" models — they spend tokens on internal reasoning before
producing output. If you see empty assistant replies, raise AGENT_MAX_TOKENS (try 2048+), or
swap to an instruct model with reliable native tool-calling such as qwen/qwen3-8b.
One tool: docs_search, retrieval over the CertMate documentation, executed
locally against the index. There is no write path, so there is no confirmation
flow.
| Command | What |
|---|---|
/help (/?) | List all commands |
/docs <query> (/ask) | Search the CertMate docs (RAG) |
/reindex [repo] [branch] | Rebuild the docs index (admin only) |
Slash commands bypass the LLM entirely — sub-200ms response, deterministic output.
The agent ships with an indexer that pulls README.md and docs/*.md from
the CertMate GitHub repo, chunks by markdown headings, and embeds with the
local text-embedding-embeddinggemma-300m. Queries embed with the same
model and cosine-rank in pure Python (no numpy / vector DB).
python -m agent.rag.indexer # defaults: fabriziosalmi/certmate@main
python -m agent.rag.indexer --repo X/Y --branch main
python -m agent.rag.indexer --paths README.md,docs/api.md
Index is written to docs_index/index.json.gz (~2 MB for 271 chunks). The
agent loads it lazily at first docs_search call — restart not required
after rebuild.
Both /docs <query> (slash, sub-50ms after embed) and the LLM tool
docs_search use the same path. The system prompt instructs the LLM to
call docs_search for any conceptual / how-to question, which keeps
small models like gemma-4-e2b grounded.
Set AGENT_ADMIN_TOKEN=<secret> to enable admin-only commands like
/reindex. Clients prove admin status by sending one of:
X-Agent-Admin: <secret> (preferred)"admin_token": "<secret>"When empty, all admin commands are disabled (404-equivalent: refused with an explanatory error in the chat). Comparison is constant-time.
In the widget, set the attribute only on admin-facing pages:
<certmate-agent endpoint="…" admin-token="MY_SECRET"></certmate-agent>
Optional. Off by default (stateless: client passes history each turn).
Set AGENT_PERSIST_CONVERSATIONS=true to:
/conversations/<session_id> (GET to fetch, DELETE to clear)session_idhistory field — survives page reloads, multi-tab use, and
works when the agent is behind a load balancerIn the widget, opt in with the persist attribute (generates a per-host
session_id in localStorage and adds a "New session" button):
<certmate-agent endpoint="…" persist></certmate-agent>
A single asyncio task runs every AGENT_CLEANUP_INTERVAL_SECONDS
(default 1 hour) and prunes:
conversation_messages older than AGENT_CONVERSATION_TTL_DAYS
(only when AGENT_PERSIST_CONVERSATIONS=true)Set AGENT_CLEANUP_INTERVAL_SECONDS=0 to disable. A pass runs on boot
so a long-stopped instance cleans backlog before serving traffic.
Set OPENROUTER_API_KEY to enable a fallback chat provider. The agent
tries the primary LM Studio first and falls back to OpenRouter only when
the primary errors out (connection, timeout, 5xx). A small circuit
breaker trips the primary after LLM_PRIMARY_FAILURE_THRESHOLD
consecutive failures and keeps it tripped for
LLM_PRIMARY_COOLDOWN_SECONDS before retrying.
Embeddings always stay on the primary (only LM Studio runs the embedding
model). The widget receives an extra status event "served via
openrouter" when the fallback handled the turn, so you can see it in the
chat log.
Pre-built workflows + manifest ship the public docs assistant
(agent.certmate.org-style) end-to-end:
.github/workflows/rebuild-docs-index.ymlRuns every Monday 06:00 UTC and on manual trigger. Pulls
fabriziosalmi/certmate@main, chunks + embeds the docs, publishes the
resulting index (gzipped JSON, never a pickle — see below) as an
index-latest GitHub Release.
Required repo secrets (Settings → Secrets and variables → Actions):
| Secret | Example value |
|---|---|
INDEX_EMBED_URL | https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1 |
INDEX_EMBED_API_KEY | Cloudflare API token (Workers AI scope) |
INDEX_EMBED_MODEL | @cf/baai/bge-base-en-v1.5 (768-dim) |
OpenAI works too:
| Secret | Example value |
|---|---|
INDEX_EMBED_URL | https://api.openai.com/v1 |
INDEX_EMBED_API_KEY | sk-... |
INDEX_EMBED_MODEL | text-embedding-3-small |
Important: the same embedding model must be configured on the runtime that serves the index. The store warns loudly if they don't match.
fly.toml + .github/workflows/deploy-fly.ymlThe Fly app fetches the published index on cold start via
AGENT_INDEX_BOOTSTRAP_URL and uses Cloudflare Workers AI (or OpenRouter)
for chat. Set AGENT_INDEX_BOOTSTRAP_SHA256 to the digest of the artifact
you intend to serve: without it, whoever can publish to that release decides
what the agent says about CertMate. Setup once:
fly apps create certmate-agent # pick any name
# Edit fly.toml: replace REPLACE_ME in LMSTUDIO_URL with your CF account id
fly secrets set LMSTUDIO_API_KEY=<token> # CF Workers AI token
fly volumes create certmate_agent_data --size 1 --region fra
fly deploy # one-shot bootstrap
Get a deploy token for GitHub:
fly tokens create deploy -x 99999h
# paste into repo secret FLY_API_TOKEN
After that, the deploy workflow runs automatically on:
main (rebuilds the image)rebuild-docs-index (just restarts machines so they re-bootstrap the index, no image rebuild)Point your DNS:
agent.certmate.org → CNAME → <app-name>.fly.dev
Fly handles TLS issuance + renewal — fitting for the CertMate ecosystem.
| Layer | Updates when | Cost |
|---|---|---|
| Docker image | code/config changes (rare) | 0 |
| Index artifact | weekly cron or doc push | $0.001/run on OpenAI; free on CF WAI |
| Fly machine | code change or index refresh | scale-to-zero, ~free under low traffic |
docker/Dockerfile + docker/docker-compose.example.yml provided.
sqlite db + RAG index live under /data (volume). Build the index from
inside the container the first time:
docker compose -f docker/docker-compose.example.yml up -d
docker compose -f docker/docker-compose.example.yml exec certmate-agent \
python -m agent.rag.indexer
After that you can rebuild via the /reindex admin command from the widget
(no shell access needed) — hot-swap, no restart.