-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add Support for HTTP Headers in URL Fetch Requests with Secure Storage for Landing Requests #20924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mvdbeek
merged 35 commits into
galaxyproject:dev
from
davelopez:explore_url_fetch_with_headers
Jan 27, 2026
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
50b7fbd
Adds support for custom headers in URL fetch requests
davelopez a823471
Adds header encryption utilities using Vault system
davelopez 19b3db7
Replaces hardcoded tool ID with a constant
davelopez b035a43
Adds header encryption/decryption for tool landing requests
davelopez 37fb0a0
Adds integration test for encrypted sensitive headers in landing requ…
davelopez d66a7e5
Adds header encryption for workflow landings
davelopez a80d669
Add integration test for workflow landing header encryption
davelopez 385d709
Simplifies sensitive header pattern matching
davelopez a9ede65
Adds logging for encryption/decryption failures in landing requests
davelopez e879af8
Refactors header encryption/decryption logic into helper methods
davelopez 16fb142
Adds logging for missing vault keys in header decryption
davelopez a91fc73
Let encrypt/decrypt headers fail fast
davelopez 6a87662
Adds recursive sensitive header detection utility
davelopez 089a589
Enforce vault configuration when sensitive headers are present
davelopez 6d29408
Introduce configurable URL header allow-list
davelopez 9be9081
Use configurable patterns for header sensitivity
davelopez ae1e89b
Update encryption/decryption API for URL-aware config
davelopez 3012450
Use URL-aware header encryption for landing requests
davelopez 2a734e1
Update headers_encryption tests for URL config
davelopez 7d3ecc4
Adds URL header allow-list management
davelopez 71d6685
Replaces generic ValueErrors with specific exceptions
davelopez 94dd7dd
Refactor UrlHeadersConfig to use ABC and Null Object pattern
davelopez 8698bc1
Implement UrlHeadersConfiguration and UrlHeadersConfigFactory
davelopez f69086b
Adapt LandingRequestManager to use UrlHeadersConfigFactory
davelopez 0c96fa4
Add utility for configuring allowed URL headers in tests
davelopez 3b6d015
Update headers encryption tests for new config factory and exceptions
davelopez 037868f
Add integration tests for URL headers configuration
davelopez 09a2aea
Adds unit tests for URL header pattern matching
davelopez d29b61a
Adds sample for URL header configuration
davelopez 1a71ca8
Adds URL headers config to mock app
davelopez d93f093
Rebuild config
davelopez 343d4b8
Removes unused null config factory method
davelopez 848f9f0
Updates sample config with sensitive auth headers
davelopez 962388c
Use correct dataset_populator method after rebase
davelopez a12a082
Adds docs for enabling HTTP headers in fetch
davelopez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../lib/galaxy/config/sample/url_headers_conf.yml.sample |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| # Enabling HTTP Headers in Fetch Requests | ||
|
|
||
| Galaxy allows users to **fetch remote data by URL** (for example via _Upload → Paste/Fetch data_ or via APIs that retrieve external resources). | ||
| By default, Galaxy **does not forward any custom HTTP headers** when fetching URLs. This restriction is intentional and is part of Galaxy’s security model. | ||
|
|
||
| Starting with recent Galaxy releases, administrators can **explicitly allow a controlled set of HTTP headers** to be sent with fetch requests, based on the target URL. This enables integrations with authenticated services (e.g. APIs requiring `Authorization` headers) while maintaining strict security boundaries. | ||
|
|
||
| This document explains **how to safely enable HTTP headers for fetch requests**, how the allow‑list mechanism works, and how to configure it. | ||
|
|
||
| ## Why Header Allow‑Listing Is Required | ||
|
|
||
| Allowing arbitrary headers in server‑side HTTP requests is dangerous. Without restrictions, users could: | ||
|
|
||
| - Access internal services (SSRF attacks) | ||
| - Exfiltrate credentials via forwarded headers | ||
| - Abuse Galaxy as a proxy to privileged networks | ||
|
|
||
| To prevent this, Galaxy implements **explicit header allow‑listing with URL pattern matching**: | ||
|
|
||
| - **No headers are allowed by default** | ||
| - Each allowed header must be explicitly configured | ||
| - Headers are only sent to URLs that match defined patterns | ||
| - Sensitive headers can be stored securely using Galaxy’s Vault | ||
|
|
||
| ## Configuration Overview | ||
|
|
||
| Header forwarding for fetch requests is controlled via a dedicated configuration file: | ||
|
|
||
| ```yaml | ||
| galaxy: | ||
| url_headers_config_file: url_headers_conf.yml | ||
| ``` | ||
|
|
||
| This file defines: | ||
|
|
||
| - Which **HTTP headers** are allowed | ||
| - For which **URL patterns** they may be sent | ||
| - Whether headers are **sensitive** (stored encrypted in the Vault) | ||
|
|
||
| If this configuration file is **not set or empty**, **no headers will ever be forwarded**. | ||
|
|
||
| ## url_headers_conf.yml Format | ||
|
|
||
| The configuration file is a YAML list of rules. Each rule applies to one or more URL patterns. | ||
|
|
||
| ### Basic Structure | ||
|
|
||
| ```yaml | ||
| - url_pattern: "https://api.example.org/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: X-API-Key | ||
| sensitive: true | ||
| ``` | ||
|
|
||
| ### Fields | ||
|
|
||
| | Field | Description | | ||
| | --------------------- | -------------------------------------------------------- | | ||
| | `url_pattern` | A regular expression matched against the full URL | | ||
| | `headers` | List of allowed HTTP headers for matching URLs | | ||
| | `headers[].name` | Exact HTTP header name (case‑insensitive) | | ||
| | `headers[].sensitive` | Whether the header value is stored securely in the Vault | | ||
|
|
||
| ## Sensitive vs Non‑Sensitive Headers | ||
|
|
||
| ### Sensitive Headers | ||
|
|
||
| Sensitive headers (for example `Authorization`, `X-API-Key`, `Cookie`) are: | ||
|
|
||
| - **Encrypted and stored in the Galaxy Vault** | ||
| - Never logged or exposed in plaintext | ||
| - Managed through Galaxy’s secure secrets infrastructure | ||
|
|
||
| Example: | ||
|
|
||
| ```yaml | ||
| - url_pattern: "https://protected.example.com/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| ``` | ||
|
|
||
| ### Non‑Sensitive Headers | ||
|
|
||
| Non‑sensitive headers may be stored in plain configuration and are typically used for: | ||
|
|
||
| - Feature flags | ||
| - API versioning | ||
| - Public metadata headers | ||
|
|
||
| Example: | ||
|
|
||
| ```yaml | ||
| - url_pattern: "https://public.example.com/.*" | ||
| headers: | ||
| - name: X-Client-Version | ||
| sensitive: false | ||
| ``` | ||
|
|
||
| ## Multiple Rules and URL Matching | ||
|
|
||
| Multiple rules may be defined. The first rule whose `url_pattern` matches the request URL is applied. | ||
|
|
||
| ```yaml | ||
| - url_pattern: "https://api.github.com/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
|
|
||
| - url_pattern: "https://raw.githubusercontent.com/.*" | ||
| headers: | ||
| - name: X-Client-Version | ||
| sensitive: false | ||
| ``` | ||
|
|
||
| ```{note} | ||
| Rules are evaluated in order. Be careful with overly broad patterns such as `.*`. | ||
| ``` | ||
|
|
||
| ## Using Headers in Practice | ||
|
|
||
| Once configured, users (or tools) may provide header values when performing fetch operations. Galaxy will: | ||
|
|
||
| 1. Validate the target URL against the allow‑list | ||
| 2. Filter headers to the allowed set | ||
| 3. Securely inject sensitive headers at request time | ||
|
|
||
| Headers not explicitly allowed **will be silently dropped**. | ||
|
|
||
| ## Security Best Practices | ||
|
|
||
| ```{warning} | ||
| Only allow headers and URL patterns that are strictly necessary. | ||
| ``` | ||
|
|
||
| Recommended practices: | ||
|
|
||
| - Prefer **narrow URL patterns** over wildcards | ||
| - Mark authentication headers as `sensitive: true` | ||
| - Avoid allowing `Cookie` headers unless absolutely required | ||
| - Never allow headers for internal or private network ranges | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| If headers are not being forwarded as expected: | ||
|
|
||
| 1. Verify `url_headers_config_file` is configured in `galaxy.yml` | ||
| 2. Confirm the URL matches the configured `url_pattern` | ||
| 3. Check that the header name matches exactly | ||
| 4. Ensure Galaxy has access to the configured Vault | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| # Allowed URL Headers Configuration | ||
| # | ||
| # This file defines which HTTP headers are allowed in URL fetch requests based | ||
| # on URL patterns, and whether they should be treated as sensitive (encrypted | ||
| # in the vault) or not. | ||
| # | ||
| # If no allow-list is specified or this file is empty/missing, NO headers will | ||
| # be allowed in URL requests. | ||
| # | ||
| # Configuration structure: | ||
| # patterns: | ||
| # - url_pattern: A regular expression pattern to match URLs | ||
| # headers: | ||
| # - name: The exact header name (case-insensitive) | ||
| # sensitive: Whether this header contains sensitive information that should | ||
| # be encrypted when stored in the database (requires vault configuration) | ||
| # | ||
| # IMPORTANT: | ||
| # ------------------------------------ | ||
| # When a URL matches MULTIPLE patterns, the union of all allowed headers is used. | ||
| # This means you can compose permissions from multiple patterns for flexibility. | ||
| # | ||
| # Example: A URL matching both pattern A (allows headers X, Y) and pattern B | ||
| # (allows headers Y, Z) will allow headers X, Y, and Z. | ||
| # | ||
| # Security: If ANY matching pattern marks a header as sensitive, it will be | ||
| # treated as sensitive (secure-by-default). | ||
| # | ||
| # The following examples are for illustration purposes only; please use only the minimum configuration for your needs. | ||
| # Examples: | ||
|
|
||
| patterns: | ||
| # GitHub API access - allow authentication headers for GitHub URLs | ||
| - url_pattern: "^https://api\\.github\\.com/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: Accept | ||
| sensitive: false | ||
| - name: X-GitHub-Api-Version | ||
| sensitive: false | ||
|
|
||
| # Generic GitHub content (raw files, releases) - no auth needed | ||
| - url_pattern: "^https://(raw\\.githubusercontent\\.com|github\\.com/.*/releases/download)/.*" | ||
| headers: | ||
| - name: Accept | ||
| sensitive: false | ||
| - name: Accept-Encoding | ||
| sensitive: false | ||
|
|
||
| # AWS S3 buckets - allow AWS authentication headers | ||
| - url_pattern: "^https://.*\\.s3\\..+\\.amazonaws\\.com/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: X-Amz-Date | ||
| sensitive: false | ||
| - name: X-Amz-Content-Sha256 | ||
| sensitive: false | ||
| - name: X-Amz-Security-Token | ||
| sensitive: true | ||
|
|
||
| # Generic cloud storage APIs | ||
| - url_pattern: "^https://.*\\.(googleapis\\.com|azure\\.com|digitaloceanspaces\\.com)/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: X-API-Key | ||
| sensitive: true | ||
| - name: Accept | ||
| sensitive: false | ||
|
|
||
| # FTP over HTTP services | ||
| - url_pattern: "^https?://ftp\\..*/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: Accept | ||
| sensitive: false | ||
|
|
||
| # Academic/research data repositories | ||
| - url_pattern: "^https://.*(zenodo\\.org|figshare\\.com|dryad\\.org|dataverse\\.org)/.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: X-API-Key | ||
| sensitive: true | ||
| - name: Accept | ||
| sensitive: false | ||
|
|
||
| # HTTPS URLs - basic headers only (most restrictive for unknown sources) | ||
| - url_pattern: "^https://.*" | ||
| headers: | ||
| - name: Authorization | ||
| sensitive: true | ||
| - name: X-Auth-Token | ||
| sensitive: true | ||
| - name: X-API-Key | ||
| sensitive: true | ||
| - name: Accept | ||
| sensitive: false | ||
| - name: Accept-Language | ||
| sensitive: false | ||
| - name: Accept-Encoding | ||
| sensitive: false | ||
| - name: Cache-Control | ||
| sensitive: false | ||
|
davelopez marked this conversation as resolved.
|
||
|
|
||
| # Security notes: | ||
| # - All matching patterns contribute their allowed headers (union of permissions) | ||
| # - If ANY pattern marks a header as sensitive, it's treated as sensitive | ||
| # - Only add headers that are absolutely necessary for your use case | ||
| # - When in doubt, mark headers as sensitive to ensure encryption | ||
| # - Patterns are order-independent, making configuration more composable | ||
| # - HTTP (non-HTTPS) URLs are generally not recommended and may be blocked | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems fine as a global config but I'd love a follow-up where this can be set on a per-file source basis, so you can allow amazon headers for s3 etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and we could then allow sensible defaults)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean directly as part of a File Source config parameter or set of parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure of the difference ? I was thinking that our file sources should automatically allow accepting and relaying relevant headers for that type of file source, so you don't need to allowlist for instance
X-Amz-Security-Token, but we'd block this by default for http/httpsUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant something like this?
BTW, thanks for the merge!
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make it