feat: support secrets in expressions and HTTP node authorization#5708
feat: support secrets in expressions and HTTP node authorization#5708andrecalil wants to merge 15 commits into
Conversation
Signed-off-by: André Calil <andre@calil.com.br>
|
👋 Commands for maintainers:
|
|
/sp-staging |
Docs Impact ReviewThis PR introduces inline Suggested docs updates:
Why: The Maintainer commands
Posted automatically by warp-gateway · commit d93dbc0 |
|
/docs-agree |
|
Risk: 65/100 (high) SummaryAdds a secrets() expression function that defers secret resolution to runtime, guards against full-map secret exposure, and wires the encryptor through the worker pipeline so HTTP node configurations can reference org secrets. Concerns
Recommended reviewers: forestileao |
Signed-off-by: André Calil <andre@calil.com.br>
|
From the security side: What happens if I enter value = |
|
From the product side: I don't like that expressions are working differently in the HTTP component compared to the rest of the system. It introduces diverging behavior, that is harder to document and maintain. Take a look at some of the previous PRs that tried to address this in the whole app, you might find some inspiration: |
shiroyasha
left a comment
There was a problem hiding this comment.
Lets try to figure out a way for all components to be able to access secrets in expressions.
Signed-off-by: André Calil <andre@calil.com.br>
|
Current version of PR was reviewed by /review-bugbot on Jun 26, 16:21 GMT-3. It flagged 2 findings. Show 2 findings1. Loop until secrets() unavailable
This change adds 2. HTTP docs use wrong syntax
The new HTTP “Inline Secrets” section documents Bugbot on commit |
Signed-off-by: André Calil <andre@calil.com.br> Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: André Calil <andre@calil.com.br>
What about this? |
|
/score-pr |
|
Clean Code Score: 82/100 This PR introduces a clear, safety-conscious design for Measured metrics
Top improvements (with concrete examples from THIS PR)
|
| - **Plain Text**: Raw text content | ||
| - **XML**: XML formatted content | ||
|
|
||
| ## Secrets in expressions |
There was a problem hiding this comment.
This shouldn't be here, right? Since this is not specific to the HTTP node, we should document it here instead
There was a problem hiding this comment.
Also, the PR title and description is no longer true. Please, update it as well so we don't mess our changelogs
There was a problem hiding this comment.
Agreed on both, addressed
Signed-off-by: André Calil <andre@calil.com.br>
Signed-off-by: André Calil <andre@calil.com.br>
Signed-off-by: André Calil <andre@calil.com.br>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2a2d1ae. Configure here.
| "parameters": spec.InvokeAction.Parameters, | ||
| }). | ||
| WithConfigurationFields(hookProvider.Configuration()). | ||
| WithSecretResolver(contexts.NewRuntimeSecretResolver(tx, w.encryptor, models.DomainTypeOrganization, workflow.OrganizationID)). |
There was a problem hiding this comment.
gRPC trigger hook skips resolver
Medium Severity
User-invoked trigger hooks still build configuration with a deferred NodeConfigurationBuilder, so secrets() placeholders in hook fields are not resolved before TriggerHookContext runs, unlike the worker trigger-hook path that now uses WithSecretResolver.
Reviewed by Cursor Bugbot for commit 2a2d1ae. Configure here.
| - Are never written back into the saved component configuration. Only the expression `secrets("api").token` is persisted; the actual token only exists in memory during execution. | ||
| - Must select a specific key. Embedding the whole secret (`secrets("api")` without a key) is rejected so the entire decrypted secret cannot leak into a URL, header, payload, or log. | ||
|
|
||
| If a referenced secret or key does not exist at execution time, the run fails with an error identifying the missing secret. |
There was a problem hiding this comment.
Missing secret keys stay silent
Medium Severity
The new expressions docs say a run fails when a referenced secret or key is missing, but runtime resolution treats a missing key inside secrets("name").key as an empty string and continues, which can send requests with blank tokens or credentials.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 2a2d1ae. Configure here.


Adds first-class secret support across components and the HTTP node, and hardens secret handling.