Research 18 min read Sep 7, 2026 9

Credential Policies Must Travel with the Secret: Testing Multi-Credential Workflow Nodes

Combining credentials in one workflow request can accidentally widen destination permissions. We examine how secret composition affects policy enforcement and downstream requests.

CredentialSecurity SecretsManagement WorkflowSecurity ApplicationSecurity SSRF MultiTenantSecurity AutonomousPentesting
S
SecureHup Team
Security Researcher · SecureHup
Credential Policies Must Travel with the Secret: Testing Multi-Credential Workflow Nodes

A workflow HTTP node combines an API token restricted to billing.example, a client certificate restricted to an internal gateway, and a generic header credential with no destination rule. The engine merges all three secrets, keeps only the most permissive policy, and sends the request to an arbitrary URL selected by an expression. Each credential worked correctly alone; composition widened their authority.

A credential is more than secret bytes. It is a capability package containing owner, tenant, destination, protocol, environment, purpose, and handling restrictions. Separating material from those restrictions during merge lets one permissive contributor carry another contributor's token somewhere its owner never approved.

Automation platforms, CI pipelines, agent tools, and low-code systems need to evaluate every contribution at the final connection. Dynamic URL resolution, redirects, retries, and worker handoff can all change the effective destination after an earlier policy check. Testing one credential against one literal URL cannot establish the composition rule.

Key Takeaways

  • Credential material and credential policy form one security object; copying headers or tokens without their constraints creates unintended authority.
  • When multiple credentials contribute to one request, destination and usage policy should normally be the safe intersection of every contributing credential, not the policy of the first or last item.
  • Expression evaluation, list ordering, redirects, DNS resolution, retries, and worker handoff can change the effective destination after an early validation check.
  • Schema validation proves that a request is well formed; it does not prove that each attached secret is authorized for the final host, path, tenant, method, or environment.
  • Autonomous pentesting should generate credential combinations and controlled destinations, then observe which synthetic canary secret actually leaves the boundary.
  • Remediation is durable only when policy travels through resolution, composition, request construction, transport, retry, and audit as an explicit typed value.

A Secret Is Not Just a String

Application code often represents credentials as maps:

{
  "headers": {"Authorization": "Bearer ..."},
  "query": {},
  "body": {}
}

This representation makes request construction convenient. It also discards why the values may be used. A more accurate model is:

CredentialCapability {
  material_reference
  owner_tenant
  allowed_destinations
  allowed_methods
  allowed_paths
  environment
  data_classification
  expiry_and_rotation_state
  redirect_policy
  egress_profile
  audit_identity
}

The request builder should not receive raw material until it has a validated capability set. Secret bytes are materialized as late as possible, used in a narrow transport context, redacted from logs, and discarded from general workflow state. Policy accompanies the reference throughout planning and execution.

Bearer credentials make the need especially clear. Whoever possesses a valid bearer token can generally use it within the authority accepted by the resource server. If the workflow sends that token to an attacker-controlled host, the attacker may not need to break encryption or authentication. Possession is the attack. Destination control is therefore part of credential protection, not an optional SSRF enhancement.

Usage Policy Is Part of Ownership

Credential owners make an implicit or explicit grant when they attach a secret to a workflow: use this credential for the intended integration. They do not grant the workflow author unlimited ability to exfiltrate it to an arbitrary endpoint. In multi-tenant platforms, the distinction is also an authorization boundary. A workflow editor may have permission to use a credential through a managed node without permission to reveal, export, or redirect its underlying value.

That distinction should survive all adapters. A service can expose "execute with credential X" while keeping material inaccessible. But if a generic HTTP node lets an expression choose any destination after X is attached, the abstraction has leaked capability. Access to use is not access to disclose.

How Multi-Credential Composition Fails

The dangerous state usually requires a combination rather than one obviously unsafe setting.

First Policy Wins, All Material Merges

Suppose credential A allows any destination because it contains a low-value public API key. Credential B contains a sensitive token and permits only api.internal.example. The engine checks the destination against A because A appears first, then merges headers from both A and B. A request to an arbitrary host passes A's policy and carries B's token.

Reversing list order may block the same request. That is a security smell: permission should not depend on array position unless order is an explicit, documented policy with a safe reason.

Last Policy Overwrites Earlier Restrictions

Some merge functions use last-write-wins semantics for whole credential objects. A later permissive credential can replace an earlier restricted destination list while retaining headers already accumulated from both. The output object looks complete, but its policy no longer describes all material inside it.

Material and Policy Resolve at Different Times

A workflow may select credentials while compiling a node, validate a literal-looking host, then evaluate an expression at runtime. If the expression changes the URL or selects a different credential, the earlier decision is stale. Conversely, a URL may be validated after expression resolution while credentials are injected later by a worker that does not receive the policy context.

Redirects Change the Recipient

The initial URL can be allowed while an HTTP redirect points elsewhere. If the client automatically forwards authorization headers across hosts, a valid initial check does not protect the secret. Redirect policy must be explicit, each hop must be evaluated, and sensitive headers should not cross origin unless narrowly intended.

DNS and Network Interpretation Drift

A hostname can resolve differently between validation and connection, through redirects, across workers, or over time. Destination policy needs a shared definition that covers canonical host, port, scheme, resolved address class, proxy behavior, and connection target. Hand-written string suffix checks are not enough.

Retry Reconstructs an Unsafe Request

The first attempt may use an in-memory validated request. A retry queue may serialize URL and headers but omit the policy proof, then execute later under different DNS, credential, or tenant state. If retry reconstructs authority from material alone, policy has again been separated from the secret.

The Composition Rule Must Be Explicit

When several credentials contribute to one outbound operation, define a composition algebra. For restrictive controls, a safe default is intersection:

effective_allowed_destinations = intersection(C1.destinations, C2.destinations, ...)
effective_allowed_methods      = intersection(C1.methods, C2.methods, ...)
effective_environments         = intersection(C1.environments, C2.environments, ...)
effective_data_policy          = most_restrictive(C1.data, C2.data, ...)
effective_redirect_policy      = most_restrictive(C1.redirects, C2.redirects, ...)
effective_expiry               = earliest(C1.expiry, C2.expiry, ...)

If the intersection is empty, composition is denied. The engine should not silently fall back to "unrestricted," ignore a credential's policy, or ask list order to decide.

Not every rule composes through mathematical intersection. Tenant ownership may require exact equality. A credential that is non-exportable may prohibit use in a generic HTTP node altogether. Two credentials may require mutually exclusive client certificates. A data residency rule may select a specific egress region. The important requirement is an explicit, tested rule for every policy field.

Fail Closed on Unknown Policy

Legacy credentials may lack new policy metadata. Treating missing fields as unrestricted makes migration easy and weakens security silently. Better options include:

  • Assign a documented restrictive default.
  • Require an administrator to classify the credential before generic use.
  • Permit only the credential's dedicated integration node.
  • Block multi-credential composition until policies are complete.
  • Run in report-only mode for a bounded migration period, then enforce.

"Unknown" is a state to manage, not a synonym for "allow all."

A Secure Outbound Request Pipeline

Ordering matters. A robust pipeline keeps policy visible through every phase.

1. Parse the Workflow Without Resolving Secrets

Load node configuration, expression templates, credential references, and workflow ownership. Validate syntax and identify which fields can influence destination, method, body, headers, proxy, and redirect behavior. Do not place secret material into the generic expression context.

2. Resolve Dynamic Inputs in a Constrained Context

Evaluate approved expressions with bounded data and deterministic semantics where possible. Produce a candidate URL, method, and request shape. Mark which values came from untrusted workflow input, upstream data, user input, or trusted configuration.

3. Load Credential Capabilities

Authorize the workflow principal to use every referenced credential. Load policy metadata and opaque secret references, not raw values. Confirm tenant, environment, credential state, expiry, and allowed node types.

4. Compose the Effective Policy

Combine restrictions using explicit field-level rules. If policies conflict or a field is unknown, deny with a useful internal reason. Record the participating credential IDs and policy versions.

5. Validate the Effective Destination

Parse the URL with one canonical parser. Enforce scheme, host, port, path, environment, proxy, and egress rules. Resolve network destinations through a controlled resolver or egress layer that can block private, link-local, loopback, metadata, and otherwise prohibited addresses according to deployment policy.

6. Materialize Secrets at the Last Moment

Fetch raw material inside the execution boundary only after authorization and destination validation. Inject it into a dedicated request object that retains the effective policy and redaction map. Never return this object to generic workflow output or expression evaluation.

7. Execute with Redirect and Connection Enforcement

Before each connection and redirect hop, verify the effective destination under the same policy. Strip sensitive headers when crossing an allowed boundary that does not explicitly permit credential forwarding. Apply rate, timeout, body-size, and response-size limits.

8. Record a Redacted, Causal Audit Event

Record workflow, node, actor, tenant, credential references, policy versions, destination classification, redirect decisions, and outcome. Do not log tokens, authorization headers, secret query parameters, or full sensitive bodies.

9. Serialize Safe Retry State

Retries should store opaque credential references, policy versions, canonical request intent, and idempotency context. Reauthorize and revalidate at execution time. Never serialize raw secret-bearing headers as durable queue payload unless a narrowly justified encrypted design makes that unavoidable.

Credential Composition Threat Model

Layer Unsafe assumption Failure Strong invariant
Credential storage Encryption at rest solves usage risk Authorized workflow leaks secret at runtime Material is released only into a policy-approved execution context
Node schema Valid configuration is safe configuration Expressions create hostile effective destination Runtime values receive semantic policy validation
List handling First or last credential represents all Restriction of another credential disappears Every contributing credential participates in policy composition
Header merge Headers are ordinary data Sensitive bearer material reaches foreign host Secret-bearing fields retain source policy and redaction
URL validation Initial hostname is final recipient Redirect or DNS changes destination Every effective connection target is checked
Worker handoff Upstream validation remains valid Principal, policy, or destination changes Worker reauthorizes and validates current state
Retry Repeating bytes repeats a safe operation Secret is resent after revocation or to changed target Retry carries intent and re-evaluates authority
Logging Debug output is harmless Tokens leak through traces or errors Secret-aware redaction follows material lineage
Multi-tenancy Workflow use permission implies secret ownership Editor redirects another tenant's credential Use, reveal, export, and administer are separate capabilities

The table shows why a vault alone cannot solve the problem. The secret can remain encrypted until milliseconds before a perfectly authorized component sends it to the wrong recipient.

Test the Combination, Not Only Each Credential

Security tests commonly create one credential, connect to its expected API, and declare success. Composition defects need differential combinations.

Build Synthetic Credential Fixtures

Create canary credentials that are harmless but uniquely observable. For example:

  • Credential A: permissive destination, marker CANARY_A.
  • Credential B: restricted to a controlled internal sink, marker CANARY_B.
  • Credential C: restricted to another host and tenant, marker CANARY_C.
  • Credential D: missing legacy policy metadata.
  • Credential E: expired or revoked.

Use a controlled HTTP sink that records only canary marker identifiers, not real secrets. Configure allowed and denied hosts, redirectors, private-address canaries, and two synthetic tenants.

Generate Pairwise and Higher-Order Cases

Test A+B and B+A to reveal ordering dependence. Add A+B+C to expose code that only compares the first two. Combine header, query, body, client-certificate, and OAuth-style credentials where supported. Vary which credential supplies authentication versus auxiliary headers.

Vary Dynamic Inputs

Exercise literal URLs, expressions, upstream-data URLs, environment variables, template functions, redirects, alternate ports, encoded hosts, DNS changes, proxy settings, and retry workers. The goal is not to bypass URL parsers with a payload catalog. It is to prove that the final connection target is evaluated under every contributing credential's policy.

Observe the Outbound Boundary

Application response codes can hide exfiltration. The primary oracle is the controlled sink or egress log: which canary marker arrived at which effective destination? Also inspect audit records, retry payloads, debug traces, and workflow outputs to ensure material did not leak through secondary channels.

Revoke During Execution

Pause a job after planning but before materialization, then revoke a credential or remove workflow permission. Resume and expect denial. Repeat before retry. This proves policy is current rather than a stale compile-time check.

For SecureHup users, the value of this approach is the ability to move from "this merge logic looks suspicious" to evidence showing whether a protected credential marker actually crossed an unauthorized boundary. That gives security teams a clearer business-impact signal, gives developers the exact composition path to repair, reduces time spent on false-positive triage, and creates a replayable validation for future workflow changes. The benefit is in the outcome, not in exposing or advertising product internals.

Credential Composition Test Cases

Scenario Credential order Destination behavior Expected result
Restricted credential alone B Allowed host Marker B reaches only allowed sink
Restricted credential alone B Denied host Request blocked before materialization
Permissive plus restricted A, B Host allowed only by A Entire request denied; B never leaves boundary
Restricted plus permissive B, A Host allowed only by A Same denial; list order has no effect
Three-way conflict A, B, C Host allowed by B only Denied because effective intersection is empty
Expression-selected URL A, B Runtime host differs from preview Runtime destination revalidated and denied
Cross-host redirect B Initial allowed, redirect denied Sensitive material not forwarded; redirect denied
Same-host safe redirect B Allowed path transition Follow only if path and redirect policy permit
DNS target change B Allowed name resolves to prohibited range Connection blocked by egress/destination policy
Worker delay B Permission removed after queueing Worker reauthorization denies execution
Credential revoked B Retry after revocation Retry denied; no serialized secret replay
Missing policy D Arbitrary host Restrictive migration policy applies, not unrestricted fallback
Cross-tenant credential C Workflow owned by tenant A Use denied before materialization
Log inspection A, B Any outcome No raw markers or authorization values in logs beyond controlled sink IDs

Include successful controls so the suite can distinguish secure enforcement from a broken network client. Assert not only denial but that secret material was never fetched or attached for denied cases when architecture supports that observation.

Evidence That Proves Credential Exposure

A strong finding should contain:

  • Synthetic workflow, node, actor, and tenant.
  • Credential references, owners, policy versions, and canary IDs.
  • Order and merge role of each credential.
  • Literal and effective URL, method, redirect chain, proxy, and resolved destination class.
  • Policy decision for each contributing credential and the composed result.
  • Whether secret material was fetched, injected, sent, logged, queued, or returned.
  • Controlled sink evidence showing exactly which marker arrived.
  • Applicable prerequisites such as expression-valued authentication, multiple credentials, or a generic request node.
  • A safe baseline and a denied negative case.
  • Fixed-build replay proving the leak no longer occurs.

Do not include reusable production tokens in evidence. Replace values with marker IDs and hashes. If a real secret was exposed during authorized incident investigation, treat it as compromised, rotate it, and tightly restrict the report.

Severity depends on the material and reachable destination. Exposing a disposable public key marker is not equivalent to leaking a tenant administrator bearer token. The test marker proves the path; impact analysis should use credential authority, data access, lifetime, rotation cost, and tenant scope without unnecessarily exercising real privileges.

Code and Architecture Remediation

Use Typed Credential Contributions

Instead of returning arbitrary header maps, each credential adapter should return a typed contribution containing opaque material references, injection instructions, policy, redaction metadata, and credential identity. Generic merge utilities must reject raw secret-bearing maps that lack provenance.

Compose Before Materializing

Calculate the effective policy from all contributions, then validate the resolved request. Only after success should the executor retrieve secrets. This reduces exposure in logs, expression contexts, previews, and failed requests.

Make Order Non-Security-Sensitive

Canonicalize credential sets or use commutative composition where appropriate. Property tests should prove that permutations yield the same allow/deny result and effective restrictions. If order legitimately controls header precedence, that behavior must not change destination authorization.

Pin Validation to Transport

Pass an immutable validated-destination object into an HTTP client that enforces it through DNS resolution, connection, proxying, and redirects. Avoid a boolean urlWasValidated flag that loses what was validated and under which policy.

Separate Credential Capabilities

Model use, reveal, export, edit, share, and delete as different actions. Workflow editors may receive mediated use without access to material. Restrict generic HTTP-node use for credentials intended only for dedicated integrations.

Redact by Lineage

Track secret-bearing values through header, query, body, error, retry, and audit construction. Key-name blocklists miss custom headers and transformed values. Redaction metadata from each credential contribution should travel with material until disposal.

CI/CD and Operational Verification

Credential composition changes can hide in generic utilities, expression evaluators, node schemas, HTTP clients, redirect settings, queue serialization, or vault adapters. Tie these components to a security regression suite.

Maintain:

  • Unit tests for every field-level composition rule.
  • Property tests proving credential-order invariance and restrictive monotonicity.
  • Expression tests confirming post-resolution destination validation.
  • Redirect, proxy, DNS, and alternate-port transport tests.
  • Multi-tenant authorization tests for mediated credential use.
  • Queue and retry tests that reauthorize current state and avoid raw material serialization.
  • Revocation race tests between planning, materialization, and connection.
  • Redaction tests across logs, traces, errors, previews, outputs, and audit records.
  • End-to-end canary tests against controlled allowed and denied sinks.

Useful metrics include credentials with complete policy metadata, generic-node credential use, denied empty intersections, order-dependent test failures, policy-to-material lineage coverage, cross-host credential-forward attempts, raw secret occurrences in telemetry, retry payloads containing material, and mean time to revoke exposed credentials. Counting vault records or encrypted fields does not measure safe runtime use.

Credential Merge Review Questions

Before releasing a node or tool that can combine credentials, verify:

  • Every secret contribution includes identity, owner, policy, and redaction metadata.
  • Workflow permission to use each credential is checked at execution time.
  • All contributing policies are composed with explicit field-level rules.
  • Missing policy fails closed or follows a documented restrictive migration mode.
  • Credential list order cannot weaken authorization.
  • Dynamic URL, method, header, body, proxy, and credential selections are validated after resolution.
  • Effective scheme, host, port, path, DNS result, proxy, and redirect are enforced at transport time.
  • Secret material is loaded only after the effective request is authorized.
  • Sensitive headers never cross hosts without explicit policy.
  • Worker and retry paths carry references and policy context, not reconstructed raw authority.
  • Revoked credentials or permissions cannot execute from a stale queued job.
  • Logs, traces, errors, previews, and workflow outputs are lineage-aware and redacted.
  • Multi-tenant tests prove that use permission does not become reveal or export permission.
  • Canary combinations and order permutations run as regression tests.

Frequently Asked Questions

Why is allowed-domain policy part of a credential rather than the HTTP node?

The node controls request behavior, but the credential owner defines where secret material may be used. Node-level egress policy and credential-level destination policy should both apply. Keeping the rule with the credential prevents a generic or newly added node from silently widening authority.

What should happen when two credentials have different allowed destinations?

For most secret-bearing outbound requests, the destination must satisfy both policies. If no destination is allowed by all contributors, deny the composition. A platform may define specialized alternatives, but it should never silently choose one credential's policy while sending another credential's material.

Does encrypting credentials at rest prevent this vulnerability?

No. Encryption protects stored material from certain disclosure paths. The workflow must decrypt or otherwise use the credential at runtime. If authorized code sends it to an unauthorized recipient, at-rest encryption has worked while usage control has failed.

Is this only an SSRF problem?

SSRF controls are relevant because they constrain outbound destinations, but the central issue is credential capability composition and disclosure. A destination may be a perfectly public attacker-controlled host rather than an internal service. Conversely, a strong egress filter does not replace tenant and credential-use authorization.

How can teams test safely without exposing real secrets?

Use unique synthetic markers or canary tokens, dedicated tenants, controlled HTTP sinks, restricted networks, and disposable workflows. Observe marker delivery and protected state, then delete fixtures. Do not use customer credentials or uncontrolled external endpoints.

Composition Should Narrow Authority

Credential data may be resolved, merged, injected, redirected, retried, sent, and logged by different components. Treating each contribution as a typed capability keeps its destination, tenant, purpose, and handling restrictions attached throughout that path. Secret material then needs to appear only after the effective destination and operation satisfy the combined policy.

Synthetic canaries can make order changes, dynamic URLs, redirects, worker retries, mixed tenants, and logging observable without using real credentials. We would expect one stable property from every combination: adding another credential contribution can preserve or reduce outbound authority, but it cannot widen where the existing secrets may go.

#CredentialSecurity #SecretsManagement #WorkflowSecurity #ApplicationSecurity #SSRF #MultiTenantSecurity #AutonomousPentesting

Was this helpful?
Share :

Find issues like this in your own codebase

SecureHup runs this exact exploit chain — discovery, enumeration and cross-tenant validation — on every deployment, automatically.