Skip to content

feat: Phase 3b + deferred features (extract languages, cache TTL, NATS control, CLI flags)#88

Merged
mostafa merged 13 commits intomainfrom
feat/extract-languages-and-deferred
May 6, 2026
Merged

feat: Phase 3b + deferred features (extract languages, cache TTL, NATS control, CLI flags)#88
mostafa merged 13 commits intomainfrom
feat/extract-languages-and-deferred

Conversation

@mostafa
Copy link
Copy Markdown
Member

@mostafa mostafa commented May 6, 2026

Summary

  • Phase 3b: Add JSONPath (jsonpath-rust) and CEL (cel) extract languages with structured extract syntax ({ expr: "...", type: jsonpath|cel|jq }) alongside the existing JQ shorthand
  • Deferred features (12 items from Phase 2-3 implementation):
    • TTL-based cache expiration + DELETE /api/v1/sources/cache/{source_id} invalidation endpoint
    • NATS control subject (rsigma.control.resolve) for remote re-resolution triggers
    • SIGHUP now triggers both rule reload and source re-resolution
    • Recursive include depth limit (max 1) to prevent cycles
    • --allow-remote-include CLI flag exposed on daemon
    • Background retry for optional sources that fail at startup
    • resolve_all_with_state() for PipelineState source tracking
    • rsigma_source_last_resolved_timestamp gauge metric
    • rsigma validate --resolve-sources flag for CI validation
    • /api/v1/status extended with dynamic_sources summary
    • rsigma resolve --dry-run flag

Test plan

  • All existing tests pass (cargo test --workspace)
  • New cache TTL tests (expiration, eviction, no-TTL persistence)
  • New include depth limit test (nested include rejected)
  • New extract language tests (JSONPath, CEL, error cases)
  • New parsing tests (structured extract syntax)
  • cargo clippy --workspace --all-targets --all-features -- -D warnings clean
  • Manual: rsigma resolve --dry-run -p pipeline.yml
  • Manual: rsigma validate --resolve-sources -p pipeline.yml rules/
  • Manual: daemon with --allow-remote-include, verify SIGHUP triggers both reload + resolve

mostafa added 13 commits May 6, 2026 23:05
Add structured extract syntax supporting three languages:
- jq (default, string shorthand): `extract: ".emails[]"`
- JSONPath (via jsonpath-rust): `extract: { expr: "$.emails[*]", type: jsonpath }`
- CEL (via cel-rust): `extract: { expr: "data.items.filter(x, x > 3)", type: cel }`

Changes:
- Add ExtractExpr enum (Jq/JsonPath/Cel) to rsigma-eval sources
- Update parser to handle both string (jq shorthand) and mapping forms
- Add File source extract field (previously only Http/Command/Nats had it)
- Implement JSONPath via jsonpath-rust (RFC 9535 compliant)
- Implement CEL via cel crate with json<->cel value conversion
- Update all resolvers to pass typed ExtractExpr
- Add integration tests for all three languages + error cases
- Add parsing tests for structured extract syntax
- Add TTL support to SourceCache (with_ttl, with_sqlite_and_ttl)
- Entries older than TTL are not returned from get()
- Add evict_expired() method for periodic cleanup
- Add DELETE /api/v1/sources/cache/{source_id} endpoint
- Store InstrumentedResolver in AppState for cache access
- Expose cache() method on InstrumentedResolver
- Add tests for TTL expiration and eviction
Prevent cycles in include expansion by rejecting included content
that itself contains Include directives. This provides a hard safety
guarantee against infinite recursion when processing dynamic pipeline
includes from potentially untrusted sources.

- Add MAX_INCLUDE_DEPTH constant (1)
- Scan parsed included transformations for nested Include directives
- Return descriptive error identifying the offending source
- Add unit test for nested include rejection
Subscribe to `rsigma.control.resolve` when daemon-nats is enabled and
dynamic sources exist. Publishing to this subject triggers re-resolution:
- Empty payload: re-resolve all sources
- Payload with source ID: re-resolve that specific source

This enables external orchestrators to proactively push cache invalidation
signals without polling the HTTP API.
SIGHUP now triggers both rule reload AND dynamic source re-resolution.
This allows operators to force-refresh all sources with a single signal,
complementing the existing interval/watch/API/NATS control mechanisms.
Add --allow-remote-include flag to the daemon subcommand that permits
include directives to reference HTTP and NATS sources. By default,
includes are restricted to local sources (file/command) for security.
Optional (required: false) sources that fail at startup now get
automatically retried 5 seconds later via the refresh scheduler.
This avoids blocking daemon startup on transient failures while
ensuring optional data becomes available once the source recovers.
Add resolve_all_with_state() that updates PipelineState source tracking
(mark_source_resolved/mark_source_failed) as sources are resolved.
This enables pipeline state consumers to observe resolution progress
and status per source, complementing the existing PipelineState API.
Records the Unix timestamp of the last successful resolution for each
dynamic source. This enables monitoring dashboards and alerting on
stale sources (e.g. source not resolved in the last N minutes).
When --resolve-sources is passed, the validate command also resolves
dynamic pipeline sources (file/command/HTTP) and expands templates.
This catches source connectivity issues during CI/pre-deploy validation
without requiring the full daemon.
When dynamic sources are configured, the status endpoint now includes
a dynamic_sources object with total sources tracked, cumulative
resolves, errors, and cache hits. Omitted entirely when no dynamic
sources are in use.
When --dry-run is passed, the resolve command lists all matching
dynamic sources with their type, required status, and refresh policy
without performing actual resolution. Useful for verifying pipeline
configuration before connecting to external sources.
- Use tokio::task::block_in_place when resolving dynamic sources in
  load_rules to prevent panic when called from async context (SIGHUP,
  file watcher hot-reload)
- Handle unused Result from CEL context.add_variable (MSRV CI fix)
@mostafa mostafa merged commit 895552a into main May 6, 2026
12 checks passed
@mostafa mostafa deleted the feat/extract-languages-and-deferred branch May 6, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant