Skip to content

feat: experimental traffic analysis#2848

Open
sobanieca-redocly wants to merge 34 commits into
mainfrom
feat/traffic-analysis
Open

feat: experimental traffic analysis#2848
sobanieca-redocly wants to merge 34 commits into
mainfrom
feat/traffic-analysis

Conversation

@sobanieca-redocly

@sobanieca-redocly sobanieca-redocly commented Jun 3, 2026

Copy link
Copy Markdown

What/Why/How?

Added two new (experimental) commands - drift and proxy for collecting traffic data and validating it against provided OpenAPI definition.

Reference

Testing

Screenshots (optional)

Check yourself

  • This PR follows the contributing guide
  • All new/updated code is covered by tests
  • Core code changed? - Tested with other Redocly products (internal contributions only)
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update has been considered

Security

  • The security impact of the change has been considered
  • Code follows company security practices and guidelines

Note

Medium Risk
Large new experimental surface (traffic parsing, security heuristics, live HTTP proxy forwarding) touches auth-related validation on captured traffic, though it reuses existing spec/validation stacks and is opt-in/experimental.

Overview
Adds two experimental CLI commands (minor @redocly/cli changesets) for comparing real HTTP traffic to OpenAPI 3.x specs.

drift ingests traffic from a file or directory (HAR, Kong, Nginx/Apache JSON, NDJSON, with auto-detection and pluggable parsers), indexes specs via @redocly/openapi-core, matches exchanges to operations (--match-mode or --server), runs built-in rules (undocumented endpoints, schema consistency, security baseline; optional owasp-api-top10), and emits pretty / JSON / CSV / SARIF reports with exit code 1 on error-level findings.

proxy runs a local reverse proxy (undici upstream) that streams HAR entries to disk and, when --api is set, reuses the same ValidationSession engine as drift for live findings plus a shutdown report. Captured HAR can be replayed through drift.

Shared implementation includes OpenAPI operation matching, AJV schema validation with readOnly/writeOnly handling, rule/plugin registries, and documentation/sidebar updates plus e2e snapshot tests for formats and outputs.

Reviewed by Cursor Bugbot for commit cf2429b. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Jun 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cf2429b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@redocly/cli Minor
@redocly/openapi-core Minor
@redocly/respect-core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@sobanieca-redocly sobanieca-redocly changed the title feat: traffic analysis poc feat: experimental traffic analysis Jun 8, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 81.46% (🎯 81%) 7459 / 9156
🔵 Statements 80.81% (🎯 80%) 7753 / 9593
🔵 Functions 84.5% (🎯 84%) 1483 / 1755
🔵 Branches 73.16% (🎯 73%) 5043 / 6893
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/cli/src/types.ts 100% 100% 100% 100%
Generated in workflow #10550 for commit cf2429b by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Performance Benchmark (Lower is Faster)

CLI Version Bundle Lint Check Config
cli-latest ▓ 1.00x (Fastest) ▓ 1.00x (Fastest) ▓ 1.00x (Fastest)
cli-next ▓ 1.01x ± 0.01 ▓ 1.01x ± 0.01 ▓ 1.00x ± 0.01

@sobanieca-redocly

Copy link
Copy Markdown
Author

@cursor review

Comment thread packages/cli/src/commands/proxy/server.ts Outdated
Comment thread packages/cli/src/commands/drift/utils/http.ts
Comment thread packages/cli/src/commands/proxy/server.ts
Comment thread packages/cli/src/commands/drift/engine/runner.ts
Comment thread packages/cli/src/commands/drift/rules/builtins/security.ts
@sobanieca-redocly

Copy link
Copy Markdown
Author

@cursor review

Comment thread packages/cli/src/commands/proxy/server.ts
Comment thread packages/cli/src/commands/proxy/server.ts Outdated
Comment thread packages/cli/src/commands/proxy/index.ts Outdated
Comment thread packages/cli/src/commands/drift/openapi/matcher.ts Outdated
@sobanieca-redocly

Copy link
Copy Markdown
Author

@cursor review

Comment thread packages/cli/src/commands/proxy/server.ts Outdated
Comment thread packages/cli/src/commands/drift/rules/builtins/schema.ts
Comment thread packages/cli/src/commands/drift/rules/builtins/schema.ts
Comment thread packages/cli/src/commands/drift/openapi/loader.ts
@sobanieca-redocly

Copy link
Copy Markdown
Author

@cursor review

Comment thread packages/cli/src/commands/drift/index.ts
Comment thread packages/cli/src/commands/drift/log-formats/ndjson.ts Outdated
Comment thread packages/cli/src/commands/drift/engine/schema-validator.ts
Comment thread packages/cli/src/commands/drift/openapi/generator.ts Outdated
@sobanieca-redocly

Copy link
Copy Markdown
Author

@cursor review

Comment thread packages/cli/src/commands/drift/log-formats/helpers.ts Outdated
@sobanieca-redocly

Copy link
Copy Markdown
Author

@cursor review

Comment thread packages/cli/src/commands/proxy/index.ts
Comment thread packages/cli/src/commands/drift/log-formats/har.ts
Comment thread packages/cli/src/commands/drift/rules/builtins/schema.ts
@sobanieca-redocly sobanieca-redocly marked this pull request as ready for review June 17, 2026 12:58
@sobanieca-redocly sobanieca-redocly requested review from a team as code owners June 17, 2026 12:58
Comment thread packages/cli/src/commands/drift/README.md Outdated
Comment thread packages/cli/src/commands/drift/README.md Outdated
Comment thread packages/cli/src/commands/drift/README.md Outdated
Comment thread packages/cli/src/commands/drift/README.md Outdated
Comment thread packages/cli/src/commands/drift/README.md Outdated
Comment thread packages/cli/src/commands/proxy/README.md Outdated
Comment thread packages/cli/src/commands/proxy/README.md Outdated
Comment thread packages/cli/src/commands/proxy/README.md Outdated
Comment thread packages/cli/src/commands/proxy/README.md
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Comment thread packages/cli/src/commands/drift/README.md Outdated
Comment thread packages/cli/src/commands/drift/utils/server.ts
type Options,
type ValidateFunction,
type Ajv2020 as Ajv2020Instance,
} from 'ajv/dist/2020.js';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be better to use our fork @redocly/ajv, this could unify usage in the repo

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks.

method: params.method,
url: params.forwardUrl.toString(),
httpVersion: `HTTP/${params.req.httpVersion}`,
cookies: parseCookieHeader(singleHeader(params.req.headers.cookie)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it's worth cleaning up sensitive data ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now this command should be used for short-lived local capture (like during e2e tests etc). Not sure about use cases yet, I would wait until we get more feedback from users before designing proper sensitive data removal...

findings.push(...ruleFindings);
}
} catch (error) {
findings.push({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it actually finding? maybe simply notify the user via the logger?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used logger instead. Thanks!

* JSON object) and serialized through a promise chain so concurrent captures
* never interleave file writes.
*/
export class HarWriter {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keeps all entries in memory and re-serializes + rewrites the entire file on every request

Maybe it would be possible to add debouncing or stream the writes using something like stream-json:
https://www.npmjs.com/package/stream-json

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the idea here. We will store data in temporary file which get's converted into HAR. This should cut memory usage.

return '***';
}

return `${value.slice(0, 4)}…`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 4 ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed magic number and named it MASK_REVEALED_PREFIX_LENGTH. This is just arbitrary number on how many characters we want to show from masked value.

reason: string;
}

interface SkippedSecurityCheck {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as SecurityIssue

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate removed. Thanks.

return { specFiles: [specPath], fromDirectory: false };
}

const YAML_OPENAPI_ROOT_KEY_RE = /^(['"]?)openapi\1\s*:/m;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

detectSpec form core?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this changes necessary ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - this is to avoid typescript issues between drift --format and lint --format

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I'm checking for some alternatives. Maybe indeed we can avoid changes in lint 👀

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed param to report-format with alias. This allows to get rid of overlap with lint command types.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the plugin system compatible with the one that's already in the core? I think having two different plugin systems for the cli is a bad idea

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case we are dealing with different purpose of rules (in this case traffic data). This means different data contracts etc. I would defer this unification when this command goes out of experimental phase.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add documentation for v2 for both commands?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added docs, but @JLekawa I will need your re-review on this one. Thanks!

Comment thread packages/cli/src/commands/proxy/har-writer.ts
Comment thread packages/cli/src/commands/drift/openapi/loader.ts Outdated
Comment thread packages/cli/src/commands/drift/index.ts
Comment thread docs/@v2/commands/drift.md Outdated
Comment thread docs/@v2/commands/drift.md Outdated
Comment thread docs/@v2/commands/drift.md Outdated
Comment thread docs/@v2/commands/drift.md Outdated
Comment thread docs/@v2/commands/drift.md Outdated
Comment thread docs/@v2/commands/proxy.md Outdated
Comment thread docs/@v2/commands/proxy.md Outdated
Comment thread docs/@v2/commands/proxy.md Outdated
Comment thread docs/@v2/commands/proxy.md Outdated
Comment thread docs/@v2/commands/proxy.md Outdated
JLekawa added 3 commits July 2, 2026 00:29
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7d65c90. Configure here.

Comment thread packages/cli/src/commands/drift/utils/server.ts
Comment thread packages/cli/src/commands/drift/log-formats/ndjson.ts Outdated
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.

4 participants