Skip to content

Comments

Add body injection support for Vanta token revocation#38

Merged
mjbraun merged 5 commits intomainfrom
vanta-integration
Dec 5, 2025
Merged

Add body injection support for Vanta token revocation#38
mjbraun merged 5 commits intomainfrom
vanta-integration

Conversation

@mjbraun
Copy link
Contributor

@mjbraun mjbraun commented Dec 4, 2025

Implemented InjectBodyProcessor and OAuthBodyProcessor to support delimiter-based token replacement in request bodies. This enables Vanta's suspend API to receive the unsealed OAuth token in the request body without exposing it in the ui-ex application. Required for Vanta integration disconnect flow in ui-ex (ref: https://developer.vanta.com/docs/oauth-flow#disconnecting-integrations-via-the-suspend-api)

Implemented InjectBodyProcessor and OAuthBodyProcessor to support
delimiter-based token replacement in request bodies. This enables
Vanta's suspend API to receive the unsealed OAuth token in the
request body without exposing it in the ui-ex application.

Features:
- ParamDelimiter support for specifying custom placeholders
- InjectBodyProcessorConfig for generic body injection
- OAuthBodyProcessorConfig for OAuth-specific body injection
- Automatic Content-Length header updates after replacement

Required for Vanta integration disconnect flow in ui-ex.
@mjbraun mjbraun requested a review from timflyio December 4, 2025 18:41
Addressing PR review feedback:
- Rename 'delimiter' to 'placeholder' throughout codebase for clarity
- Use github.com/icholy/replace for streaming replacement instead of io.ReadAll
- Prevents memory exhaustion on large request bodies
- Add comprehensive test cases for body injection processors

Changes:
- Update ParamDelimiter constant to ParamPlaceholder
- Convert InjectBodyProcessorConfig to use streaming replace.Chain()
- Convert OAuthProcessorConfig body injection to use streaming
- Convert OAuthBodyProcessorConfig to use streaming
- Add dependency on github.com/icholy/replace v0.6.0
- Add test coverage for:
  - Simple and multiple placeholder replacements
  - Custom placeholders from params and config
  - Large bodies (50KB+) with streaming
  - OAuth access and refresh tokens
  - Nil/empty bodies
Enhance test coverage to verify mutual exclusivity of header and body injection:
- Body injection: verify Authorization header is NOT set
- Header injection: verify body is NOT modified

This ensures the dual-mode behavior of OAuthProcessorConfig works correctly:
- With placeholder param → only body is modified
- Without placeholder param → only Authorization header is set
processor.go Outdated
chain := replace.Chain(r.Body, replace.String(placeholder, c.Token))

// Buffer the replaced content to calculate Content-Length
var buf bytes.Buffer
Copy link
Contributor

Choose a reason for hiding this comment

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

hrm.. we still are reading the whole thing into memory (into buf) to get the content length. I think you can set the r.ContentLength to zero and r.Body to the replacement chain, and it should be able to stream the body using chunked encoding without knowing the content length ahead of time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to use the 0 contentlength and r.Body = io.NopCloser(chain)

Copy link
Contributor

Choose a reason for hiding this comment

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

this should do it I think, though I would try it out just to make sure. since this shouldnt break any existing use cases you can test it after deploying.

Switch from buffering entire request bodies to using chunked transfer
encoding (ContentLength = 0) when performing token replacement. This
eliminates memory overhead for large request bodies by streaming through
the replace.Chain without needing to calculate content length upfront.

Updated processors:
- InjectBodyProcessorConfig.Processor()
- OAuthBodyProcessorConfig.Processor()
- OAuthProcessorConfig.Processor() (when placeholder provided)

Removed unused MaxBodySizeForInjection constant.
Copy link
Contributor

@timflyio timflyio left a comment

Choose a reason for hiding this comment

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

lgtm

@mjbraun mjbraun marked this pull request as ready for review December 5, 2025 00:31
@mjbraun mjbraun merged commit e161ecd into main Dec 5, 2025
1 check passed
@mjbraun mjbraun deleted the vanta-integration branch December 5, 2025 00:32
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.

2 participants