Feature type
New integration (framework / SDK) — adds an outbound log-forwarder layer
alongside the existing ActivityStream and SignedAuditLog tiers. This
is the ROADMAP Phase 3 item
("SIEM integration (Splunk/Datadog/Azure Sentinel)").
This issue intentionally scopes only the foundation slice: the
extension point, the default schema mapper, and one universal HTTPS
transport. Vendor-specific transports (syslog, Splunk HEC, Sentinel DCR)
and detection-content bundles (Sigma rules) are out of scope for this
discussion — they belong in follow-up issues once the foundation lands.
What problem does this solve?
ActivityStream already captures the right events with the right fields
(user_id, risk_score, policy_decision, matched_rules,
owasp_refs, autonomy_level, delegation_chain), and SignedAuditLog
gives them a tamper-evident HMAC chain. But until those events reach the
enterprise SOC, several controls remain checked-in-letter-but-not-in-spirit:
- NIST SP 800-53 AU-2 / AU-6 ("audit events" / "audit review") implies
centralized review, not per-host JSONL.
- ISMS-P 2.9 (로그관리) / 2.11 (이상행위 분석) and the 2024 Korean
Financial Services AI guideline require integration with the central
SOC stack for 통합관제 / UEBA correlation.
- Insider-threat / UEBA signals need to live next to IdP, EDR, DLP
in the SIEM — local ~/.aigis/ cannot satisfy this.
A forwarder layer closes the integration gap without changing the on-disk
tiers (which remain authoritative).
Proposed solution (foundation slice only)
A new aigis/forwarders/ package with three pieces:
LogForwarder ABC — bounded background queue, batching, exception
isolation, Redactor Protocol that runs before the schema mapper so
PIPA / GDPR data-minimization can strip sensitive fields before they
leave the process.
- Default schema: ECS 8.x — natively indexed by Elastic / Wazuh,
DCR-ingestible by Microsoft Sentinel, CIM-derivable for Splunk. Aigis-
native fields preserved under aigis.* namespace so analysts never
lose matched_rules, owasp_refs, delegation_chain, autonomy_level.
HttpJsonForwarder — stdlib-only HTTPS POST sink covering Splunk
HEC, Sentinel DCR, Elastic _bulk, Datadog Logs, and generic in-VPC
ingest. NDJSON / array body, optional gzip, exponential backoff,
4xx-vs-5xx-aware retry.
ActivityStream.add_forwarder() hook — Tier-4 dispatch after the
existing local / global / alerts tiers. Default behavior unchanged
when no forwarder is registered.
Hard invariants:
- A misconfigured or down SIEM cannot stop the agent or corrupt JSONL.
- Zero new required dependencies —
pyproject.toml untouched.
- ECS / CEF / OCSF / Splunk CIM are pluggable mappers behind one Protocol.
Open questions for maintainer guidance
I'd like to align on these before writing the merge-targeted PR:
- Default schema — ECS vs OCSF? ECS has the broader installed base
today (Elastic, Wazuh, Sentinel-via-DCR, Splunk-via-CIM). OCSF is
gaining traction (AWS Security Lake, Cisco) but consumer support is
thinner. Default ECS, ship OCSF as a sibling mapper? Or the reverse?
- Module location —
aigis/forwarders/ vs aigis/middleware/?
CONTRIBUTING.md documents aigis/middleware/ for integration modules,
but middleware in the current codebase wraps LLM-provider request /
response flow, which is semantically different from outbound log
shipping. New top-level seems cleaner; happy to be wrong.
- Queue persistence. Current design is an in-memory bounded queue.
Should the foundation already include an on-disk spool (SQLite WAL) so
a process crash during a SIEM outage doesn't drop the queued tail, or
defer it? Cost ~150 LOC + an integrity contract with the JSONL tier.
- PII redaction defaults. Should
details / rule sample text be
redacted by default when no Redactor is configured? Keeping the data
preserves analyst signal but adds a PIPA-by-default footgun for KR
deployments. Lean: keep current (preserve), document the redactor as
mandatory in compliance contexts.
Reference implementation (for context only)
A working prototype of the foundation slice lives on my fork — purely as
a discussion artifact, not a PR request. It's the simplest way to
make the design above concrete:
I'll rework / move / re-architect whatever direction makes sense after
this discussion before opening a real PR against killertcell428/aigis.
Are you willing to contribute?
cc / context: https://github.com/killertcell428/aigis/blob/master/ROADMAP.md#L160
Feature type
New integration (framework / SDK) — adds an outbound log-forwarder layer
alongside the existing
ActivityStreamandSignedAuditLogtiers. Thisis the ROADMAP Phase 3 item
("SIEM integration (Splunk/Datadog/Azure Sentinel)").
This issue intentionally scopes only the foundation slice: the
extension point, the default schema mapper, and one universal HTTPS
transport. Vendor-specific transports (syslog, Splunk HEC, Sentinel DCR)
and detection-content bundles (Sigma rules) are out of scope for this
discussion — they belong in follow-up issues once the foundation lands.
What problem does this solve?
ActivityStreamalready captures the right events with the right fields(
user_id,risk_score,policy_decision,matched_rules,owasp_refs,autonomy_level,delegation_chain), andSignedAuditLoggives them a tamper-evident HMAC chain. But until those events reach the
enterprise SOC, several controls remain checked-in-letter-but-not-in-spirit:
centralized review, not per-host JSONL.
Financial Services AI guideline require integration with the central
SOC stack for 통합관제 / UEBA correlation.
in the SIEM — local
~/.aigis/cannot satisfy this.A forwarder layer closes the integration gap without changing the on-disk
tiers (which remain authoritative).
Proposed solution (foundation slice only)
A new
aigis/forwarders/package with three pieces:LogForwarderABC — bounded background queue, batching, exceptionisolation,
RedactorProtocol that runs before the schema mapper soPIPA / GDPR data-minimization can strip sensitive fields before they
leave the process.
DCR-ingestible by Microsoft Sentinel, CIM-derivable for Splunk. Aigis-
native fields preserved under
aigis.*namespace so analysts neverlose
matched_rules,owasp_refs,delegation_chain,autonomy_level.HttpJsonForwarder— stdlib-only HTTPS POST sink covering SplunkHEC, Sentinel DCR, Elastic
_bulk, Datadog Logs, and generic in-VPCingest. NDJSON / array body, optional gzip, exponential backoff,
4xx-vs-5xx-aware retry.
ActivityStream.add_forwarder()hook — Tier-4 dispatch after theexisting local / global / alerts tiers. Default behavior unchanged
when no forwarder is registered.
Hard invariants:
pyproject.tomluntouched.Open questions for maintainer guidance
I'd like to align on these before writing the merge-targeted PR:
today (Elastic, Wazuh, Sentinel-via-DCR, Splunk-via-CIM). OCSF is
gaining traction (AWS Security Lake, Cisco) but consumer support is
thinner. Default ECS, ship OCSF as a sibling mapper? Or the reverse?
aigis/forwarders/vsaigis/middleware/?CONTRIBUTING.mddocumentsaigis/middleware/for integration modules,but middleware in the current codebase wraps LLM-provider request /
response flow, which is semantically different from outbound log
shipping. New top-level seems cleaner; happy to be wrong.
Should the foundation already include an on-disk spool (SQLite WAL) so
a process crash during a SIEM outage doesn't drop the queued tail, or
defer it? Cost ~150 LOC + an integrity contract with the JSONL tier.
details/ rule sample text beredacted by default when no
Redactoris configured? Keeping the datapreserves analyst signal but adds a PIPA-by-default footgun for KR
deployments. Lean: keep current (preserve), document the redactor as
mandatory in compliance contexts.
Reference implementation (for context only)
A working prototype of the foundation slice lives on my fork — purely as
a discussion artifact, not a PR request. It's the simplest way to
make the design above concrete:
ruff checkclean.I'll rework / move / re-architect whatever direction makes sense after
this discussion before opening a real PR against
killertcell428/aigis.Are you willing to contribute?
cc / context: https://github.com/killertcell428/aigis/blob/master/ROADMAP.md#L160