Repository navigation
lantern 0.1.6
Every item on the 0.1.5 roadmap is now built, plus two security-hardening
passes over the agent's own attack surface, bounded multi-agent delegation,
full session CRUD, and a real daemon mode.
Roadmap, closed
- AD / Impacket-style tooling (
--offensive-gated):GetUserSPNs.py
(Kerberoasting),GetNPUsers.py(AS-REP roasting),crackmapexec
(SMB/WinRM/LDAP enumeration - a closed allowlist of read-only modules,
no execution method ever accepted),bloodhound-python(AD relationship
collection). - API-schema-aware testing:
api_schema_scanwalks an OpenAPI/Swagger
document and resolves the real auth requirement per endpoint, honoring
operation-levelsecurity: []overriding a document default.
graphql_introspectreports whether introspection is enabled and, if so,
the schema's types and root names. Both passive - they read a schema the
target already serves and call nothing it describes. - Cloud posture / container exposure:
cloud_bucket_check(anonymous
S3/Azure Blob/GCS listing, credential-free),container_expose_check
(unauthenticated Docker daemon API or anonymous Kubelet API, one read-only
request),host_kubehunter(active,--offensive-gated). - Daemon mode:
lantern queue add/list/removepluslantern daemon,
a polling loop against Lantern's own SQLite file (no socket, no HTTP
server) that claims and runs jobs one at a time and stops cleanly on
SIGINT/SIGTERM. - Bounded multi-agent delegation: researcher/coder/pentester can call
delegate_taskto spin off one sub-investigation. Four properties hold by
construction, not just by docstring: a delegated task's tools are a
subset of the calling role's own list, it shares the parent's scope/
--offensivegrant exactly, it cannot delegate again, and it's capped at
5 steps per call / 10 total per role turn. Now rendered inchatas a
nested block (↳ researcher delegates: "...") and logged to the audit
trail as its own event. - Full session CRUD:
lantern delete <flow-id> --yes;chat's/new
and/delete <flow-id> yes, exercised live under a pty.
Five more native tools, and role-scoped tool schemas
waf_fingerprint (WAF/CDN signature match from one ordinary response - no
payloads - so a zero-finding scan can tell "clean" apart from "a WAF ate
every probe"), secret_scan (regex match for cloud/SaaS keys and JWTs on
text another tool already captured, every hit masked), host_testssl,
host_gobuster, and host_amass (active, --offensive-gated - distinct
from the passive subdomain_enum below).
Registry::defs_for(focus) now scopes the tool schemas sent to the model
to each role's own focus list instead of sending all 26 tools' schemas to
every role - pentester's per-call overhead drops to ~2,656 tokens,
researcher ~1,898, coder ~953, reflector ~444, down from a flat worst case
that was already over 3,400 before this release added anything.
Passive subdomain discovery, and prompts that earn their own budget
subdomain_enum (certificate-transparency lookup via crt.sh - touches no
target infrastructure). A role whose prompt repeats enough of its own
vocabulary (named injection classes, GraphQL/IAM/Kerberoasting/JWT/
container-escape, ...) now earns up to 4 extra steps over its static
default. Engagement-profile prompts (WebApp/Api/InternalAd/Cloud/
NetworkInfra) add a short block naming the right taxonomy (OWASP, MITRE
ATT&CK, CIS) and what the toolset genuinely cannot check for that profile,
so a role says "no tool for that" instead of narrating a check it never ran.
Security hardening
- Scope bypass, closed: a bare CIDR target (e.g. msfconsole's RHOSTS)
was checked against only its network's base address, so a scope of
10.0.0.0/24waved through a target of10.0.0.0/8. A CIDR target is
now checked as the whole range it names. - DNS drift pinned to the audit trail: host-tool targets are resolved
immediately before execution; a hostname that now resolves outside every
declared scope range is refused, and the resolved IPs land in the command
audit row (newresolved_ipscolumn) and inlantern reporteither way. - Runtime limits now actually device-derived: concurrency and child
memory limits were computed from the live device profile and then
discarded in favor of hardcoded defaults. They now derive from the host's
real cores/RAM unlessLANTERN_CONCURRENCY/LANTERN_CHILD_MEM_MBis set. - Unbounded reads, closed on both sides: every in-process HTTP fetch
facing a target (http_probe,waf_fingerprint,dir_bruteforce,
subdomain/search lookups) buffered a full response before truncating -
a hostile or oversized response could grow this process's own heap
without limit. New capped readers stop at the limit instead of reading
past it first. The same pattern is fixed on the model-provider side
(Anthropic/OpenAI-compatible/Ollama embedding clients, the setup wizard's
model-list fetch). - Target-facing
User-Agentis now configurable (LANTERN_USER_AGENT),
self-identifying by default. - Cross-process flow-id collision, fixed: flow IDs mixed only a
millisecond timestamp and a per-process counter that resets on every
start - twolantern runprocesses launched in the same millisecond
produced the same flow ID and shared one row. The OS pid is now mixed in;
verified against 20 real concurrent processes, 20 distinct IDs. chatTUI: the approval card's default highlight flipped from
"allow once" to "deny" (matching the module's own "deny-by-inaction"
doc comment - a reflexive Enter no longer grants active testing);
str::floor_char_boundaryreimplemented locally rather than relying on
a newer Rust than the declared 1.85 minimum; aMutexguard held across
an.awaitin the steering-queue drain is fixed (clippy
await_holding_lock).
README
Rewritten twice for structure and to close out every section the roadmap
items touch - "Roles and delegation," "Session lifecycle," "Concurrency,
sessions, and the daemon," and a corrected "Detectability, traces, and the
agent's own attack surface" - plus GETTING_STARTED.md kept in sync with
the current tool and test counts.
Verified
- 317 tests pass, 0 failed, 1 ignored (the live NVD query) across the
workspace: lantern-core 58, lantern-llm 33, lantern-tools 109,
lantern-agent 65, lantern-cli 52. cargo check --workspace --all-targets --release: zero warnings.lantern doctoron the reference device (4-core aarch64, 8.5 GiB RAM):
reports the device-derived runtime (concurrency 4, child limit 503 MB,
token budget 6000) and exits in ~91 ms.- Built and tested on this device at 2.8 GB / 29 GB free (under its own 20%
floor) -doctorcorrectly reportsUNDER THE FLOOR, confirming the
0.1.5 behavior (the floor guardssetup, notrun/ask/chat) still
holds. - Release binary: 9,464,360 bytes (aarch64).
Upgrade
git pull
cargo build --release # ~/.cargo/bin/cargo if it is not on PATH
./target/release/lantern doctorSchema migrates automatically to v3 (the resolved_ips column from 0.1.5's
work and the new queue table) - no manual step, and flows recorded on
earlier versions still render.
Attached: lantern-v0.1.6-aarch64-linux-gnu (9,464,360 bytes), built on
Debian 13 / aarch64, kernel 6.18. For anything else, build from source as
above.