mallcop

package module
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: MIT Imports: 1 Imported by: 0

README

mallcop

Open-source security monitoring for small cloud operators. AI-native. Go.

mallcop is a Go-native security monitoring CLI. It ingests your cloud and SaaS audit events, runs 17 deterministic detectors that look for real-world attack patterns, then drives each finding through an LLM-backed investigation cascade (triage → investigate → deep panel → committee consensus) before paging a human. Findings and resolutions are written to a git-native store, so every decision is durable, replayable, and auditable. The rules corpus is embedded in the binary — mallcop is a single standalone executable.

Install

One line (Linux & macOS):

curl -fsSL https://mallcop.app/install.sh | sh

Downloads the prebuilt binary for your platform, verifies its checksum, and installs it to /usr/local/bin or ~/.local/bin (no sudo). It's a single static binary with the detection rules baked in — no runtime, no config file.

Go toolchain:

go install github.com/mallcop-app/mallcop/cmd/mallcop@latest

Release binaries:

Pre-built binaries for Linux (amd64/arm64) and macOS (Apple Silicon) are attached to each GitHub release. Download the archive for your platform, extract, and place mallcop on your PATH.

Quickstart

1. Install mallcop (see above).

2. Scaffold a store and sample events:

mallcop init

init creates a store/ directory (the git-backed findings store) and a sample events.jsonl, then prints the exact next-step commands below.

3. Run a scan over the sample events:

mallcop scan --events events.jsonl --store store

That's it — no config file. scan reads the events, runs the detectors, drives findings through the cascade, and commits findings + resolutions into store/. With no inference endpoint configured, every finding force-escalates (the documented fail-safe), so the command works end to end with zero credentials.

4. (Optional) Enable LLM-driven resolution. Point mallcop at an inference endpoint via the MALLCOP_INFERENCE_URL / MALLCOP_API_KEY pivot — a vendor URL

  • key for BYOK, or the Forge URL + a mallcop-sk-* tenant key for the metered managed path:
export MALLCOP_INFERENCE_URL=https://api.mallcop.app
export MALLCOP_API_KEY=mallcop-sk-...
mallcop scan --events events.jsonl --store store

5. Inspect what was recorded:

mallcop status --store store

Commands

Command Purpose
mallcop scan Full agentic scan: connect → detect → cascade → store. Requires --store.
mallcop detect Offline detection only. Reads events JSONL on stdin, writes findings JSONL on stdout. No inference key.
mallcop init Scaffold a findings store + sample events and print runnable next steps.
mallcop status Report findings/resolutions recorded in a store. Requires --store.
mallcop config Print the effective scan config resolved from the environment.
mallcop scan
# File connector (default): scan a local events JSONL file
mallcop scan --events events.jsonl --store store

# GitHub connector (built into the core binary): scan a GitHub org's audit log
export GITHUB_APP_ID=...
export GITHUB_APP_PRIVATE_KEY=...      # PEM, or a path to it
export GITHUB_INSTALLATION_ID=...
mallcop scan --connector github --github-org my-org --store store

Flags: --store (required), --events (file path or - for stdin), --connector (file | github), --github-org, --baseline, --workers, --json, --base-url.

Exit codes: 0 no findings, 1 findings present, 2 scan failure.

Architecture

mallcop scan
  → connector        — fetch/ingest audit events (file or github)
  → detectors        — 17 deterministic attack-pattern detectors
  → cascade          — triage → investigate → deep panel → committee consensus
  → git store        — durable, replayable findings + resolutions

The cascade resolves each finding through escalating tiers and ends in a committee consensus vote: on every RESOLVE, the gate re-runs the cascade and any-escalate-wins — a safety-first, asymmetric policy because a missed attack (false negative) is catastrophic while an over-escalation merely pages a human. The operator rules corpus is embedded in the binary, so the scan is fully standalone — no external rules files to ship or keep in sync.

Connectors

The core binary ships two built-in connectors:

  • file (default) — reads normalized event JSONL from --events.
  • github — pulls a GitHub org's audit log directly, using GITHUB_APP_ID / GITHUB_APP_PRIVATE_KEY / GITHUB_INSTALLATION_ID.

Additional connectors ship as standalone binaries in the sibling repo mallcop-app/mallcop-connectors. Each emits event JSONL that you pipe into mallcop scan --events -:

mallcop-connector-aws-cloudtrail --region us-east-1 \
  | mallcop scan --events - --store store

Currently shipped standalone connectors: AWS CloudTrail, Azure Activity Log, GCP Cloud Logging, GitHub Audit Log, M365 Management Activity, Okta System Log.

Not yet ported: container_logs, supabase, vercel.

Detectors

17 deterministic detectors run on every scan (and via mallcop detect):

auth-failure-burst       config-drift            dependency-tamper
exfil-pattern            git-oops                injection-probe
log-format-drift         malicious-skill         new-actor
new-external-access      priv-escalation         rate-anomaly
secrets-exposure         unusual-login           unusual-resource-access
unusual-timing           volume-anomaly

Content-only detectors (e.g. injection-probe, secrets-exposure, git-oops, config-drift, dependency-tamper, malicious-skill) fire without any history. The baseline-dependent detectors (new-actor, priv-escalation, unusual-login, unusual-timing, volume-anomaly, rate-anomaly, exfil-pattern) use an optional --baseline JSON file for historical context.

License

MIT. See LICENSE.

Documentation

Overview

corpus.go — the embedded operator-decisions corpus.

//go:embed cannot traverse "..", so the embed directive must live in a .go file at a directory level whose subtree contains the corpus. The corpus is at <root>/agents/rules/operator-decisions.yaml, so ONLY the repo root qualifies. This is the sole production package at the root (hello_test.go is the external `mallcop_test` package, which Go permits to coexist with `mallcop` in the same directory).

The bytes are exposed so the production runtime loaders (core/agent's escalate-route floor and core/tools' operator-rules loader) can FALL BACK to a baked-in corpus when no on-disk corpus can be located — e.g. a standalone `/tmp/mallcop` binary with MALLCOP_REPO_ROOT unset and no project marker above it. This is a strict FALLBACK: an on-disk corpus (binary-walk hit or MALLCOP_REPO_ROOT) always wins, so dev edit-and-reload of the corpus is preserved. See the loaders' corpusBytes helpers.

This package imports ONLY "embed" — it carries no dependency that could let the floor path reach inference, so importing it from core/agent and core/tools does not violate either import-lint.

Index

Constants

This section is empty.

Variables

View Source
var OperatorDecisionsYAML []byte

OperatorDecisionsYAML is the byte-for-byte contents of agents/rules/operator-decisions.yaml at build time. Because //go:embed copies the exact file, these bytes are identical to the on-disk corpus the SHA pin (core/tools.expectedOperatorRulesSHA256) describes — by construction, with no separate copy that could drift. The embed==disk test makes that invariant explicit and catches a stale checked-in pin.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
Deploy-repo scaffold + creation (mallcoppro-f3b): `mallcop init --create-repo owner/name` turns the plain local scaffold runInit already writes (mallcop.yaml, store/, events.jsonl) into a customer DEPLOYMENT repo pushed to a real GitHub repository, so the customer never compiles mallcop locally — a scheduled GitHub Action does.
Deploy-repo scaffold + creation (mallcoppro-f3b): `mallcop init --create-repo owner/name` turns the plain local scaffold runInit already writes (mallcop.yaml, store/, events.jsonl) into a customer DEPLOYMENT repo pushed to a real GitHub repository, so the customer never compiles mallcop locally — a scheduled GitHub Action does.
cmd
baseline command
Command baseline builds and queries mallcop baseline frequency tables.
Command baseline builds and queries mallcop baseline frequency tables.
detector-config-drift command
detector-config-drift reads events JSONL from stdin and emits findings JSONL to stdout for configuration change events: security group modifications, IAM policy changes, MFA disabling, and audit log modifications.
detector-config-drift reads events JSONL from stdin and emits findings JSONL to stdout for configuration change events: security group modifications, IAM policy changes, MFA disabling, and audit log modifications.
detector-dependency-tamper command
detector-dependency-tamper reads events JSONL from stdin and emits findings JSONL to stdout for dependency supply chain tampering: package version changes, unexpected additions, hash mismatches, and typosquatting indicators.
detector-dependency-tamper reads events JSONL from stdin and emits findings JSONL to stdout for dependency supply chain tampering: package version changes, unexpected additions, hash mismatches, and typosquatting indicators.
detector-exfil-pattern command
detector-exfil-pattern reads events JSONL from stdin and emits findings JSONL to stdout for events that indicate data exfiltration: unusual outbound data volumes, bulk access to many resources in a short window, or download events that exceed baseline frequency thresholds.
detector-exfil-pattern reads events JSONL from stdin and emits findings JSONL to stdout for events that indicate data exfiltration: unusual outbound data volumes, bulk access to many resources in a short window, or download events that exceed baseline frequency thresholds.
detector-git-oops command
detector-git-oops reads events JSONL from stdin and emits findings JSONL to stdout for dangerous git operations: force pushes, branch deletions, and commit messages containing secret-looking strings.
detector-git-oops reads events JSONL from stdin and emits findings JSONL to stdout for dangerous git operations: force pushes, branch deletions, and commit messages containing secret-looking strings.
detector-injection-probe command
detector-injection-probe reads events JSONL from stdin and emits findings JSONL to stdout for events that contain prompt injection attempts in their payload fields.
detector-injection-probe reads events JSONL from stdin and emits findings JSONL to stdout for events that contain prompt injection attempts in their payload fields.
detector-malicious-skill command
detector-malicious-skill reads events JSONL from stdin and emits findings JSONL to stdout for skill-related events that contain suspicious URLs, encoded payloads, or excessive permission requests.
detector-malicious-skill reads events JSONL from stdin and emits findings JSONL to stdout for skill-related events that contain suspicious URLs, encoded payloads, or excessive permission requests.
detector-new-actor command
detector-new-actor reads events JSONL from stdin, compares each actor against the baseline known-actors set, and emits findings JSONL to stdout for actors not seen in the baseline period.
detector-new-actor reads events JSONL from stdin, compares each actor against the baseline known-actors set, and emits findings JSONL to stdout for actors not seen in the baseline period.
detector-priv-escalation command
detector-priv-escalation reads events JSONL from stdin and emits findings JSONL to stdout for events that indicate a privilege escalation — role grants, permission changes, or admin promotions — not already in the baseline.
detector-priv-escalation reads events JSONL from stdin and emits findings JSONL to stdout for events that indicate a privilege escalation — role grants, permission changes, or admin promotions — not already in the baseline.
detector-rate-anomaly command
detector-rate-anomaly reads events JSONL from stdin and emits findings JSONL to stdout for events that show API rate anomalies: burst requests, orders-of-magnitude jumps above baseline, or unusual endpoint access patterns.
detector-rate-anomaly reads events JSONL from stdin and emits findings JSONL to stdout for events that show API rate anomalies: burst requests, orders-of-magnitude jumps above baseline, or unusual endpoint access patterns.
detector-secrets-exposure command
detector-secrets-exposure reads events JSONL from stdin and emits findings JSONL to stdout when event payload fields contain secrets in cleartext: API keys, tokens, passwords, and credentials matching known formats.
detector-secrets-exposure reads events JSONL from stdin and emits findings JSONL to stdout when event payload fields contain secrets in cleartext: API keys, tokens, passwords, and credentials matching known formats.
detector-unusual-login command
detector-unusual-login reads events JSONL from stdin, compares each login event against a baseline of known user patterns, and emits findings JSONL to stdout for logins that deviate from baseline.
detector-unusual-login reads events JSONL from stdin, compares each login event against a baseline of known user patterns, and emits findings JSONL to stdout for logins that deviate from baseline.
detector-unusual-timing command
detector-unusual-timing reads events JSONL from stdin and emits findings JSONL to stdout for events that occur at UTC hours not seen for that actor in the baseline period.
detector-unusual-timing reads events JSONL from stdin and emits findings JSONL to stdout for events that occur at UTC hours not seen for that actor in the baseline period.
detector-volume-anomaly command
detector-volume-anomaly reads events JSONL from stdin, counts events per (source, event_type) group, and emits findings JSONL to stdout when the observed count exceeds 3× the baseline count for that group.
detector-volume-anomaly reads events JSONL from stdin, counts events per (source, event_type) group, and emits findings JSONL to stdout when the observed count exceeds 3× the baseline count for that group.
exam-transcript-dump command
cmd/exam-transcript-dump renders a judge-visible Markdown transcript from exam fixture data and a heal disposition's resolution JSON.
cmd/exam-transcript-dump renders a judge-visible Markdown transcript from exam fixture data and a heal disposition's resolution JSON.
mallcop command
Command mallcop is the customer-facing CLI for running mallcop scans.
Command mallcop is the customer-facing CLI for running mallcop scans.
mallcop-credential-theft-verify command
Command mallcop-credential-theft-verify is a veracity-gate hook binary that enforces the Credential Theft Test rule from the investigate disposition.
Command mallcop-credential-theft-verify is a veracity-gate hook binary that enforces the Credential Theft Test rule from the investigate disposition.
mallcop-eval command
Command mallcop-eval runs the portable eval harness over the SHA-pinned scenario corpus and prints the report as JSON.
Command mallcop-eval runs the portable eval harness over the SHA-pinned scenario corpus and prints the report as JSON.
mallcop-exam-report command
Command mallcop-exam-report aggregates judge:verdict messages from a campfire into a structured exam report (report.json + report.md).
Command mallcop-exam-report aggregates judge:verdict messages from a campfire into a structured exam report (report.json + report.md).
notify-discord command
Command notify-discord is the Discord outbound notification adapter.
Command notify-discord is the Discord outbound notification adapter.
notify-email command
notify-slack command
notify-teams command
notify-telegram command
connect
exec
Package exec is the process-boundary cloud Connector: it runs a sibling connector binary (from the separate mallcop-connectors module) as a child process, reads the normalized event JSONL the sibling writes to stdout, and captures the incremental cursor the sibling writes to stderr — so that `mallcop scan` auto-pulls a cloud source in one pass instead of the manual `mallcop-connector-aws > events.jsonl` two-step.
Package exec is the process-boundary cloud Connector: it runs a sibling connector binary (from the separate mallcop-connectors module) as a child process, reads the normalized event JSONL the sibling writes to stdout, and captures the incremental cursor the sibling writes to stderr — so that `mallcop scan` auto-pulls a cloud source in one pass instead of the manual `mallcop-connector-aws > events.jsonl` two-step.
github
Package github is the portable GitHub Connector: it pulls org activity from the GitHub API and normalizes it to []event.Event so the detector floor (core/detect) and the rest of the scan pipeline run unchanged.
Package github is the portable GitHub Connector: it pulls org activity from the GitHub API and normalizes it to []event.Event so the detector floor (core/detect) and the rest of the scan pipeline run unchanged.
overlay
Package overlay is the shared LEARNED-MAPPING overlay: a widen-only data layer that maps a connector's raw action string to a known event_type, consulted ONLY when the connector's own classification fell through to its default bucket ("<sourceID>_other").
Package overlay is the shared LEARNED-MAPPING overlay: a widen-only data layer that maps a connector's raw action string to a known event_type, consulted ONLY when the connector's own classification fell through to its default bucket ("<sourceID>_other").
core
agent
Package agent holds the SECURITY-CRITICAL pre-LLM floor for finding resolution plus the minimal anthropic.Client interface the agent loop (built in a later wave) consumes.
Package agent holds the SECURITY-CRITICAL pre-LLM floor for finding resolution plus the minimal anthropic.Client interface the agent loop (built in a later wave) consumes.
collect
Package collect is the OFFLINE, DETERMINISTIC feedstock-collector half of the self-extension loop.
Package collect is the OFFLINE, DETERMINISTIC feedstock-collector half of the self-extension loop.
config
Package config is the loader for mallcop.yaml — the one file mallcop reads.
Package config is the loader for mallcop.yaml — the one file mallcop reads.
connect
Package connect is the INPUT seam of the scan pipeline: it turns a source of raw activity into the normalized []event.Event the detector floor consumes.
Package connect is the INPUT seam of the scan pipeline: it turns a source of raw activity into the normalized []event.Event the detector floor consumes.
detect
Package detect provides offline, deterministic security detection over a corpus of normalized events.
Package detect provides offline, deterministic security detection over a corpus of normalized events.
detect/authored
Package authored is the human-bootstrapped REGISTRATION AGGREGATOR for agent-authored detectors (K7 L1).
Package authored is the human-bootstrapped REGISTRATION AGGREGATOR for agent-authored detectors (K7 L1).
detect/authored/synthmarker
Package synthmarker is the REFERENCE agent-authored detector.
Package synthmarker is the REFERENCE agent-authored detector.
eval
artifacts.go — write the harness's per-scenario result JSON, per-scenario TRANSCRIPTS, and the classifier summary to disk (§4.4 result JSON, §4.7 transcript audit).
artifacts.go — write the harness's per-scenario result JSON, per-scenario TRANSCRIPTS, and the classifier summary to disk (§4.4 result JSON, §4.7 transcript audit).
inference
Package inference holds the network seam that satisfies core/agent.Client.
Package inference holds the network seam that satisfies core/agent.Client.
lint
Package lint hosts the repo-level import-lint guard for the core/ tree.
Package lint hosts the repo-level import-lint guard for the core/ tree.
observe
Package observe holds the THREE pure observable force-escalate predicates the cascade's structural-confidence gate scores, plus every helper / threshold / map they read — extracted VERBATIM from core/eval/scenario_tools.go so that the eval scenarioToolRunner AND the production core/toolrun.Runner call ONE shared implementation and get BYTE-IDENTICAL booleans + details.
Package observe holds the THREE pure observable force-escalate predicates the cascade's structural-confidence gate scores, plus every helper / threshold / map they read — extracted VERBATIM from core/eval/scenario_tools.go so that the eval scenarioToolRunner AND the production core/toolrun.Runner call ONE shared implementation and get BYTE-IDENTICAL booleans + details.
pipeline
Package pipeline is the ORCHESTRATOR that assembles the four core seams into one agentic scan cycle:
Package pipeline is the ORCHESTRATOR that assembles the four core seams into one agentic scan cycle:
store
Package store is the git-repo source of truth for mallcop's six append-only streams: events, findings, resolutions, baseline, conversation, and directives.
Package store is the git-repo source of truth for mallcop's six append-only streams: events, findings, resolutions, baseline, conversation, and directives.
toolrun
Package toolrun is the PRODUCTION ToolRunner — the live agent.ToolRunner the scan pipeline wires into the cascade (CascadeOptions.Tools).
Package toolrun is the PRODUCTION ToolRunner — the live agent.ToolRunner the scan pipeline wires into the cascade (CascadeOptions.Tools).
tools
casefold.go — case-insensitive structured-record parsing at the boundary (portable-agent-architecture.md §3.7).
casefold.go — case-insensitive structured-record parsing at the boundary (portable-agent-architecture.md §3.7).
Package detecthost is the wazero-based HOST runtime for wasip1 WASM detector sidecars.
Package detecthost is the wazero-based HOST runtime for wasip1 WASM detector sidecars.
examples
sidecar-detector command
Command sidecar-detector is the example wasip1 sidecar main: it is compiled with GOOS=wasip1 GOARCH=wasm and run inside the wazero host (github.com/mallcop-app/mallcop/detecthost), never invoked as a native binary.
Command sidecar-detector is the example wasip1 sidecar main: it is compiled with GOOS=wasip1 GOARCH=wasm and run inside the wazero host (github.com/mallcop-app/mallcop/detecthost), never invoked as a native binary.
sidecar-detector/exampledetector
Package exampledetector is the trivial rule used to PROVE the wasip1 sidecar delivery path end to end (mallcoppro-f70): the same detect.Detector implementation is run two ways — in-process (an ordinary Go call) and wrapped by detecthost as a real, compiled .wasm sidecar — and the two runs must produce byte-identical findings.
Package exampledetector is the trivial rule used to PROVE the wasip1 sidecar delivery path end to end (mallcoppro-f70): the same detect.Detector implementation is run two ways — in-process (an ordinary Go call) and wrapped by detecthost as a real, compiled .wasm sidecar — and the two runs must produce byte-identical findings.
internal
exam
Package exam provides types and loader logic for mallcop exam scenarios.
Package exam provides types and loader logic for mallcop exam scenarios.
testutil/cannedbackend
Package cannedbackend provides a minimal HTTP server that mimics Forge's /v1/chat/completions and /v1/messages endpoints for integration and e2e tests.
Package cannedbackend provides a minimal HTTP server that mimics Forge's /v1/chat/completions and /v1/messages endpoints for integration and e2e tests.
pkg
detectorhost
Package detectorhost is the GUEST-side harness for a WASM detector sidecar.
Package detectorhost is the GUEST-side harness for a WASM detector sidecar.
ghauth
Package ghauth mints GitHub App installation access tokens with a stdlib-only RS256 JWT.
Package ghauth mints GitHub App installation access tokens with a stdlib-only RS256 JWT.
notify
Package notify holds the reusable outbound-notification send paths shared by the cmd/notify-* adapter binaries and the scan pipeline's gated emit step.
Package notify holds the reusable outbound-notification send paths shared by the cmd/notify-* adapter binaries and the scan pipeline's gated emit step.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL