|
| 1 | +# Enabling HTTP Headers in Fetch Requests |
| 2 | + |
| 3 | +Galaxy allows users to **fetch remote data by URL** (for example via _Upload → Paste/Fetch data_ or via APIs that retrieve external resources). |
| 4 | +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. |
| 5 | + |
| 6 | +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. |
| 7 | + |
| 8 | +This document explains **how to safely enable HTTP headers for fetch requests**, how the allow‑list mechanism works, and how to configure it. |
| 9 | + |
| 10 | +## Why Header Allow‑Listing Is Required |
| 11 | + |
| 12 | +Allowing arbitrary headers in server‑side HTTP requests is dangerous. Without restrictions, users could: |
| 13 | + |
| 14 | +- Access internal services (SSRF attacks) |
| 15 | +- Exfiltrate credentials via forwarded headers |
| 16 | +- Abuse Galaxy as a proxy to privileged networks |
| 17 | + |
| 18 | +To prevent this, Galaxy implements **explicit header allow‑listing with URL pattern matching**: |
| 19 | + |
| 20 | +- **No headers are allowed by default** |
| 21 | +- Each allowed header must be explicitly configured |
| 22 | +- Headers are only sent to URLs that match defined patterns |
| 23 | +- Sensitive headers can be stored securely using Galaxy’s Vault |
| 24 | + |
| 25 | +## Configuration Overview |
| 26 | + |
| 27 | +Header forwarding for fetch requests is controlled via a dedicated configuration file: |
| 28 | + |
| 29 | +```yaml |
| 30 | +galaxy: |
| 31 | + url_headers_config_file: url_headers_conf.yml |
| 32 | +``` |
| 33 | +
|
| 34 | +This file defines: |
| 35 | +
|
| 36 | +- Which **HTTP headers** are allowed |
| 37 | +- For which **URL patterns** they may be sent |
| 38 | +- Whether headers are **sensitive** (stored encrypted in the Vault) |
| 39 | +
|
| 40 | +If this configuration file is **not set or empty**, **no headers will ever be forwarded**. |
| 41 | +
|
| 42 | +## url_headers_conf.yml Format |
| 43 | +
|
| 44 | +The configuration file is a YAML list of rules. Each rule applies to one or more URL patterns. |
| 45 | +
|
| 46 | +### Basic Structure |
| 47 | +
|
| 48 | +```yaml |
| 49 | +- url_pattern: "https://api.example.org/.*" |
| 50 | + headers: |
| 51 | + - name: Authorization |
| 52 | + sensitive: true |
| 53 | + - name: X-API-Key |
| 54 | + sensitive: true |
| 55 | +``` |
| 56 | +
|
| 57 | +### Fields |
| 58 | +
|
| 59 | +| Field | Description | |
| 60 | +| --------------------- | -------------------------------------------------------- | |
| 61 | +| `url_pattern` | A regular expression matched against the full URL | |
| 62 | +| `headers` | List of allowed HTTP headers for matching URLs | |
| 63 | +| `headers[].name` | Exact HTTP header name (case‑insensitive) | |
| 64 | +| `headers[].sensitive` | Whether the header value is stored securely in the Vault | |
| 65 | + |
| 66 | +## Sensitive vs Non‑Sensitive Headers |
| 67 | + |
| 68 | +### Sensitive Headers |
| 69 | + |
| 70 | +Sensitive headers (for example `Authorization`, `X-API-Key`, `Cookie`) are: |
| 71 | + |
| 72 | +- **Encrypted and stored in the Galaxy Vault** |
| 73 | +- Never logged or exposed in plaintext |
| 74 | +- Managed through Galaxy’s secure secrets infrastructure |
| 75 | + |
| 76 | +Example: |
| 77 | + |
| 78 | +```yaml |
| 79 | +- url_pattern: "https://protected.example.com/.*" |
| 80 | + headers: |
| 81 | + - name: Authorization |
| 82 | + sensitive: true |
| 83 | +``` |
| 84 | + |
| 85 | +### Non‑Sensitive Headers |
| 86 | + |
| 87 | +Non‑sensitive headers may be stored in plain configuration and are typically used for: |
| 88 | + |
| 89 | +- Feature flags |
| 90 | +- API versioning |
| 91 | +- Public metadata headers |
| 92 | + |
| 93 | +Example: |
| 94 | + |
| 95 | +```yaml |
| 96 | +- url_pattern: "https://public.example.com/.*" |
| 97 | + headers: |
| 98 | + - name: X-Client-Version |
| 99 | + sensitive: false |
| 100 | +``` |
| 101 | + |
| 102 | +## Multiple Rules and URL Matching |
| 103 | + |
| 104 | +Multiple rules may be defined. The first rule whose `url_pattern` matches the request URL is applied. |
| 105 | + |
| 106 | +```yaml |
| 107 | +- url_pattern: "https://api.github.com/.*" |
| 108 | + headers: |
| 109 | + - name: Authorization |
| 110 | + sensitive: true |
| 111 | +
|
| 112 | +- url_pattern: "https://raw.githubusercontent.com/.*" |
| 113 | + headers: |
| 114 | + - name: X-Client-Version |
| 115 | + sensitive: false |
| 116 | +``` |
| 117 | + |
| 118 | +```{note} |
| 119 | +Rules are evaluated in order. Be careful with overly broad patterns such as `.*`. |
| 120 | +``` |
| 121 | + |
| 122 | +## Using Headers in Practice |
| 123 | + |
| 124 | +Once configured, users (or tools) may provide header values when performing fetch operations. Galaxy will: |
| 125 | + |
| 126 | +1. Validate the target URL against the allow‑list |
| 127 | +2. Filter headers to the allowed set |
| 128 | +3. Securely inject sensitive headers at request time |
| 129 | + |
| 130 | +Headers not explicitly allowed **will be silently dropped**. |
| 131 | + |
| 132 | +## Security Best Practices |
| 133 | + |
| 134 | +```{warning} |
| 135 | +Only allow headers and URL patterns that are strictly necessary. |
| 136 | +``` |
| 137 | + |
| 138 | +Recommended practices: |
| 139 | + |
| 140 | +- Prefer **narrow URL patterns** over wildcards |
| 141 | +- Mark authentication headers as `sensitive: true` |
| 142 | +- Avoid allowing `Cookie` headers unless absolutely required |
| 143 | +- Never allow headers for internal or private network ranges |
| 144 | + |
| 145 | +## Troubleshooting |
| 146 | + |
| 147 | +If headers are not being forwarded as expected: |
| 148 | + |
| 149 | +1. Verify `url_headers_config_file` is configured in `galaxy.yml` |
| 150 | +2. Confirm the URL matches the configured `url_pattern` |
| 151 | +3. Check that the header name matches exactly |
| 152 | +4. Ensure Galaxy has access to the configured Vault |
0 commit comments