Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ jobs:
- name: Verify npm package metadata
run: pnpm package:check

- name: Generate release verification artifacts
run: pnpm release:artifacts

commitlint:
name: Commitlint
if: github.event_name == 'pull_request'
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ jobs:
- name: Verify npm package metadata
run: pnpm package:check

- name: Generate release verification artifacts
run: pnpm release:artifacts

- name: Upload release verification artifacts
uses: actions/upload-artifact@v4
with:
name: mimir-release-${{ inputs.version }}
path: release-artifacts/

- name: Publish
run: npm publish --access public --provenance
env:
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ coverage/
.env
.DS_Store
private/**
.kb/storage/
.kb/cache/
.kb/
.mimir/
*.tgz
release-artifacts/
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
- `kb init` and `kb install-skill` must keep generated local Mimir state ignored in target
repositories. By default, add `.kb/`, `.mimir/`, and private raw-document paths to the
target repository `.gitignore`.
- Keep confidentiality features low-friction: local-only network policy, redaction before
indexing, metadata-only access logs, bounded MCP retrieval, and `security-audit` should work
from default config.
- Use Context7 before changing dependencies or public APIs that rely on external libraries.
- Run `pnpm validate` before opening a release pull request or publishing. It covers
Biome, TypeScript, Vitest, build output, production CLI/MCP smoke tests, and npm package
Expand All @@ -31,6 +34,8 @@
- `src/mcp.ts` exposes Mimir as an MCP stdio server for agents.
- `src/gitignore.ts` owns target-repository `.gitignore` entries for local generated Mimir
state.
- `src/security.ts`, `src/network.ts`, `src/redaction.ts`, and `src/access-log.ts` own the
privacy and confidentiality hardening layer.
- `skills/mimir/SKILL.md` is the bundled portable agent skill.
- `.kb/`, `.mimir/`, and project `private/` folders are local user data or generated agent
state in target repositories and must not be committed.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 0.3.0 - 2026-06-28

- Add confidentiality hardening defaults: local-only Ollama network policy, built-in
redaction before indexing, metadata-only access logs, and bounded MCP retrieval.
- Add `kb security-audit` for zero-telemetry, network, redaction, gitignore, storage, and
MCP posture checks.
- Add `kb destroy-index --yes` to remove generated vector indexes.
- Add release verification artifacts: npm tarball, SHA256 checksums, SBOM, and manifest.
- Document air-gapped operation, threat model, MCP hardening, and secure deletion limits.

## 0.2.1 - 2026-06-28

- Add GitHub Sponsors funding metadata and document suggested sponsor tiers.
Expand Down
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pnpm exec kb ingest
pnpm exec kb search "vendor invoice status"
pnpm exec kb ask "What do the documents prove?"
pnpm exec kb audit
pnpm exec kb security-audit
pnpm exec kb status
```

Expand All @@ -121,6 +122,7 @@ npx kb ingest
npx kb search "vendor invoice status"
npx kb ask "What do the documents prove?"
npx kb audit
npx kb security-audit
npx kb status
```

Expand Down Expand Up @@ -157,6 +159,7 @@ MCP tools exposed:
- `mimir_search`
- `mimir_ask`
- `mimir_audit`
- `mimir_security_audit`

Print the bundled skill path from the installed package:

Expand All @@ -175,12 +178,40 @@ your-project/
.kb/config.json # local config
.kb/sources.txt # optional extra source paths
.kb/storage/ # generated LanceDB index
.kb/access.log # metadata-only access log
```

The package never ships project documents. `kb init` adds gitignore entries for `.kb/`
and `private/**`, and `kb install-skill` keeps `.mimir/` ignored as generated local agent
state.

## Confidentiality Defaults

Mimir is designed for private repositories and sensitive local evidence.

- Zero telemetry: no analytics or document content is sent to JCode Labs.
- Local-only network policy: Ollama must be on loopback by default.
- Redaction before indexing: common secrets and identifiers are redacted before chunks are
embedded and stored.
- Metadata-only access logs: query hashes and action metadata are logged, not raw queries.
- MCP is read-focused and bounded by `mcpMaxTopK`.
- Generated local state is ignored by Git.

Run:

```bash
pnpm exec kb security-audit --strict
```

Remove the generated vector index:

```bash
pnpm exec kb destroy-index --yes
```

For air-gapped operation, release verification, secure deletion limits, and threat model details,
read [`SECURITY-HARDENING.md`](./SECURITY-HARDENING.md).

## Supported Files

- Markdown: `.md`, `.mdx`
Expand All @@ -200,10 +231,19 @@ state.
"rawDir": "private",
"storageDir": ".kb/storage",
"sourcesFile": ".kb/sources.txt",
"accessLogPath": ".kb/access.log",
"tableName": "chunks",
"ollamaHost": "http://localhost:11434",
"networkPolicy": "local-only",
"embedModel": "nomic-embed-text",
"llmModel": "gemma4:latest",
"redaction": {
"enabled": true,
"builtIn": true,
"patterns": []
},
"accessLog": true,
"mcpMaxTopK": 10,
"topK": 5,
"chunkSize": 1200,
"chunkOverlap": 150
Expand All @@ -215,9 +255,15 @@ Environment overrides:
- `KB_RAW_DIR`
- `KB_STORAGE_DIR`
- `KB_SOURCES_FILE`
- `KB_ACCESS_LOG_PATH`
- `KB_OLLAMA_HOST`
- `KB_NETWORK_POLICY`
- `KB_EMBED_MODEL`
- `KB_LLM_MODEL`
- `KB_REDACTION_ENABLED`
- `KB_REDACTION_BUILT_IN`
- `KB_ACCESS_LOG`
- `KB_MCP_MAX_TOP_K`
- `KB_TOP_K`
- `KB_CHUNK_SIZE`
- `KB_CHUNK_OVERLAP`
Expand All @@ -235,6 +281,9 @@ const answer = await ask("What documents support the project timeline?")
## Privacy

- Embeddings and answers use local Ollama by default.
- Remote Ollama hosts are blocked unless `networkPolicy` explicitly allows them.
- Built-in redaction runs before indexing by default.
- Access logs store query hashes, not raw queries.
- The vector index is stored locally.
- Raw private documents should stay in the target repository's ignored `private/` folder.
- Do not put secrets or scans inside this package repository.
Expand Down
156 changes: 156 additions & 0 deletions SECURITY-HARDENING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Mimir Security Hardening

Mimir is a local-first knowledge base for private project documents. It is built to minimize
data movement, but it is not a certified high-assurance system.

## Current Guarantees

- Zero telemetry: Mimir does not send usage analytics or document content to JCode Labs.
- Local-only network policy by default: document text can only be sent to loopback Ollama hosts
unless the repository explicitly opts in to broader network access.
- Redaction before indexing: built-in DLP patterns redact common secrets and identifiers before
chunks are embedded and stored.
- Metadata-only access logs: access logs contain action metadata and query hashes, not raw
queries or retrieved text.
- Generated local state is ignored by Git: `.kb/`, `.mimir/`, and `private/**` are ignored by
default.
- MCP is read-focused: destructive tools are not exposed over MCP, and MCP retrieval is capped by
`mcpMaxTopK`.
- npm releases are published with provenance from the protected GitHub Actions workflow.
- Release artifacts include a package tarball, SHA256 checksums, SBOM, and manifest.

## Threat Model

Mimir protects against accidental repository leaks, accidental remote LLM usage, accidental secret
indexing, and weak release traceability.

Mimir does not protect against a compromised local machine, malicious dependencies already present
in the runtime, a user with filesystem access to the same checkout, or forensic recovery from an
unencrypted disk.

## At-Rest Encryption

Native encrypted LanceDB storage is not implemented yet. For sensitive environments, put the
repository and `.kb/` on an encrypted volume:

- macOS: FileVault or an encrypted APFS volume.
- Linux: LUKS, fscrypt, or an encrypted VM disk.
- Containers/VMs: mount `.kb/` on an encrypted host volume.

`kb destroy-index --yes` removes generated index files, but secure deletion on SSDs and copy-on-write
filesystems cannot be guaranteed without encrypted storage and key destruction.

## Air-Gapped Operation

Prepare artifacts on an internet-connected build machine:

```bash
pnpm install --frozen-lockfile
pnpm build
pnpm release:artifacts
```

Move the generated tarball from `release-artifacts/` into the offline environment and install it:

```bash
pnpm add -D ./jcode.labs-mimir-<version>.tgz
pnpm exec kb init
pnpm exec kb ingest
```

Ollama and the required models must also be preloaded inside the offline environment.

## Zero Network Posture

Default config:

```json
{
"ollamaHost": "http://localhost:11434",
"networkPolicy": "local-only"
}
```

Allowed policies:

- `local-only`: only loopback hosts such as `localhost` and `127.0.0.1`.
- `allow-private`: loopback and private LAN hosts.
- `allow-any`: any host. Use only when the remote endpoint is explicitly trusted.

Run:

```bash
pnpm exec kb security-audit --strict
```

## DLP Redaction

Built-in redaction is enabled by default for common secret and identifier shapes: private keys,
JWTs, API tokens, emails, IBANs, and card-like numbers.

Custom patterns can be added in `.kb/config.json`:

```json
{
"redaction": {
"enabled": true,
"builtIn": true,
"patterns": [
{
"name": "internal_case_id",
"pattern": "CASE-[0-9]+",
"replacement": "[CASE]"
}
]
}
}
```

Redaction changes the indexed text, not the raw files under `private/`.

## MCP Hardening

MCP gives an agent access to retrieved private context. Use it only for agents running under the
same trust boundary as the repository.

Mimir MCP defaults:

- read-focused tools only;
- no index deletion tool exposed over MCP;
- bounded retrieval through `mcpMaxTopK`;
- metadata-only access logging.

For team use, prefer one checkout per user or per role. Mimir does not implement RBAC.

## Release Verification

The protected npm workflow runs validation, generates release artifacts, and publishes with
provenance:

```bash
npm publish --access public --provenance
```

Release artifacts include:

- npm tarball;
- `SHA256SUMS`;
- CycloneDX SBOM;
- `release-manifest.json`.

Verify checksums offline with:

```bash
sha256sum -c SHA256SUMS
```

On macOS:

```bash
shasum -a 256 -c SHA256SUMS
```

## External Audit Status

No external security audit has been completed yet. Treat Mimir as useful hardening for private
developer workflows, not as military-grade certified software.
10 changes: 10 additions & 0 deletions dist/access-log.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Config } from "./types.js";
export interface AccessLogEvent {
action: "ingest" | "search" | "ask" | "destroy-index";
query?: string;
topK?: number;
resultCount?: number;
redactions?: number;
}
export declare function recordAccess(config: Config, event: AccessLogEvent): Promise<void>;
//# sourceMappingURL=access-log.d.ts.map
1 change: 1 addition & 0 deletions dist/access-log.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions dist/access-log.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/access-log.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading