Skip to content

Add report only mode Groovy interceptor #2822

Open

Description

@ebariaux

Add an interceptor that will only log a summary of what has been intercepted but not block anything.
That information will be useful to known what new facades/features to provide or what changes need to be planned on rules.

Activity

  1. ebariaux commented on Jun 3, 2026

    @ebariaux
    ContributorAuthor

    Define these things first so the data is useful:

    1. Coverage
      Report both phases:

      • deployment-time script.run() in RulesetDeployment.compileRulesGroovy
      • runtime when/then closure execution around engine.fire(...) in RulesEngine.doFire

      Registering only around script.run() misses the important part: rule closures execute later.

    2. Event Schema
      Do not log argument values. Log normalized signatures:

      • ruleset id/name/version/lang/scope
      • phase: DEPLOYMENT or RUNTIME
      • operation: method call, static call, constructor, property get/set, attribute get/set, array get/set
      • receiver class or constructed class
      • member/property/method name
      • argument type names
      • return type name if easy
      • count, first seen, last seen

      Avoid values because facts, notifications, webhook payloads, headers, and credentials can leak.

    3. Aggregation
      Do not emit one log per intercepted call. Groovy rules use collections, streams, optionals, closures, and query builders; raw call volume will be noisy.

      Aggregate by normalized signature per ruleset version. Emit first-seen log lines and periodic summaries.

    4. Classification
      Even in report-only, classify signatures:

      • allowed-known: expected facade/simple value use
      • unknown: candidate for allowlist/facade work
      • dangerous: would be denied later

      Dangerous examples: System, Runtime, ProcessBuilder, File, URL, sockets, reflection, classloaders, Class.forName, getClass, .class, metaClass, thread creation, @grab.

    5. Fail-Open Semantics
      Report-only must never break rule execution. If reporting fails, log that reporting failed and call through.

    6. Config
      Add a clear mode, probably:

      • OFF
      • REPORT
      • ENFORCE

      Also add filters: all rules, only a realm, only a ruleset id, max unique signatures per deployment, summary interval.

    7. Known Gaps
      Runtime interception will not fully cover compile-time behavior such as imports, annotations, AST transforms, and @grab. Add a cheap pre-parse/source or AST inventory for those so they show up in the report too.

    Implementation shape:

    class ReportingGroovyInterceptor extends GroovyInterceptor {
    @OverRide
    public Object onMethodCall(Invoker invoker, Object receiver, String method, Object... args) throws Throwable {
    report("METHOD", receiver != null ? receiver.getClass() : null, method, args);
    return invoker.call(receiver, method, args);
    }

      @Override
      public Object onStaticCall(Invoker invoker, Class receiver, String method, Object... args) throws Throwable {
          report("STATIC", receiver, method, args);
          return invoker.call(receiver, method, args);
      }
    
      @Override
      public Object onNewInstance(Invoker invoker, Class receiver, Object... args) throws Throwable {
          report("NEW", receiver, "<init>", args);
          return invoker.call(receiver, null, args);
      }
    

    }

    Then wrap execution with register/unregister:

    interceptor.register();
    try {
    script.run();
    } finally {
    interceptor.unregister();
    }

    And similarly around Groovy engine.fire(...).

  2. self-assigned this
    on Jun 3, 2026
  3. linked a pull request that will close this issueAdd reporting about groovy rules #2827on Jun 5, 2026
  4. ebariaux commented on Jun 12, 2026

    @ebariaux
    ContributorAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions