Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Get rid of allowed_http_hosts in v2 manifest #1988

Merged
merged 4 commits into from
Oct 31, 2023
Merged

Get rid of allowed_http_hosts in v2 manifest #1988

merged 4 commits into from
Oct 31, 2023

Conversation

rylev
Copy link
Collaborator

@rylev rylev commented Oct 30, 2023

This removes allowed_http_hosts in favor of allowed_outbound_hosts.

allowed_outbound_hosts has become strict in that it is required to follow the form "$SCHEME://$HOST:$PORT" where $SCHEME can be "*" or a specific scheme, $HOST can be "*" or a specific host, and $PORT can be "*", a specific port, or a port range. In the future we will allow lists of schemes, hosts, and ports.

Some notes:

  • "insecure:allow-all" is done away with in favor of *://*:*.
  • Schemes are required but if you don't care you can use globs: *://example.com

rylev added 2 commits October 30, 2023 12:58
Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
@rylev rylev requested review from lann and itowlson October 30, 2023 17:17
.context("`allowed_outbound_hosts` is malformed")?;
}
spin_outbound_networking::AllowedHostsConfig::parse(&component.allowed_outbound_hosts)
.context("`allowed_outbound_hosts` is malformed")?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Definitely low priority but it might be nice to eventually move this parsing into serde for the nice errors you get out of toml deserialization.

crates/manifest/src/allowed_http_hosts.rs Outdated Show resolved Hide resolved
crates/manifest/tests/ui/maximal.json Show resolved Hide resolved
@@ -12,6 +12,6 @@ component = "outbound-pg"
[component.outbound-pg]
environment = { DB_URL = "host=localhost user=postgres dbname=spin_dev" }
source = "target/wasm32-wasi/release/rust_outbound_pg.wasm"
allowed_outbound_hosts = ["localhost:5432"]
allowed_outbound_hosts = ["postgres://localhost:5432"]
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure where this scheme comes from? There's no scheme used in the connection string.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We're not doing literal equality checking on strings: the scheme in this config signifies that you are allowed to make postgres outbound calls to that host and port (and not, for example, http calls).

@@ -12,7 +12,7 @@ component = "wasi-http-async"

[component.wasi-http-async]
source = "target/wasm32-wasi/release/wasi_http_rust_streaming_outgoing_body.wasm"
allowed_http_hosts = ["insecure:allow-all"]
allowed_outbound_hosts = ["https://*:*"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this still allow HTTP (not HTTPS) for localhost scenarios?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think in the current implementation it would but that seems a bit odd. The most consistent thing would be to require {http, https}://*:* (note that the list syntax is not yet implemented), but that is admittedly a bit annoying.

examples/http-tinygo-outbound-http/spin.toml Show resolved Hide resolved
@tschneidereit
Copy link
Contributor

We just discussed this in the Spin Up meeting, and I think we should hold off on removing the existing way of doing this this shortly before the release.

Landing this change requires a lot of documentation update, solid work on devUX to ensure that developers aren't left stranded because they don't know how to migrate, and potentially also some deeper conversation about the exact design and ergonomics of allowed_outbound_hosts.

Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
@rylev
Copy link
Collaborator Author

rylev commented Oct 31, 2023

Ok. I've pushed some changes that I think address most of the issues:

allowed_http_hosts in v2

We will continue to support allowed_http_hosts in v2 manifests but we will emit a warning when it is used.

For example, say I have the following in my manifest:

allowed_http_hosts = ["foo.com"]

This will work as expected (http traffic to foo.com will be allowed), but the following warning will be emitted:

Warning: Use of the deprecated field `allowed_http_hosts` - to fix, replace the use of `allowed_http_hosts` with `allowed_outbound_hosts = ["https://foo.com:443"]

Default ports

The allowed_outbound_hosts syntax now allows for omitting the port. If the port is omitted, the scheme is used to determine which port is allowed. For example, an https scheme allows for port 443 and a redis scheme allows for port 6379.

A full description of the allowed_outbound_hosts syntax

The allowed_outbound_hosts syntax is composed of three parts: a scheme, a host, and an optional port in the following form:

$SCHEME://$HOST:$PORT

Each of these elements can be either a specific string (e.g., scheme can be 'http' or 'redis') or a glob which allows anything. Additionally ports allow for port ranges using the syntax ($START..$END). In the future, we can easily extend this to more flexible syntax such as lists (e.g., {redis, mysql}://example.com:{3000, 4000, 5000..5999}).

  • Scheme: The scheme decides which type of request is allowed. For example, if you specify 'redis' as the scheme than redis requests are allowed but postgres, mysql, http, etc. are not. Note that this is independent of whether the url the user is using in their code has the scheme or not. Making a request from the user's code to 'example.com' or 'redis://example.com' are both permitted when the allowed_outbound_hosts list includes 'redis://example.com'.
  • Host: the host must match exactly between the url the user provides to an outbound networking interface being used and the configuration in allowed_outbound_hosts. For example Redis requests to 'example.com' are permitted by allowed_outbound_hosts = ["redis://example.com"] but requests to 'subdomain.example.com' are not (even if 'subdomain.example.com' redirects to 'example.com').
    • There is one special host "self" that allows making requests back to the current application.
  • Port: The port used to make the request must be in the range specified by the config. For example, a request to 'example.com:4001' is allowed by allowed_outbound_hosts = ["*://example.com:4001"] and allowed_outbound_hosts = ["*://example.com:4000..4999"] but is not allowed by allowed_outbound_hosts = ["*://example.com:4000"].

@rylev rylev force-pushed the no-more-http-hosts branch from 4a52b09 to a875503 Compare October 31, 2023 10:48
@rylev rylev force-pushed the no-more-http-hosts branch from a875503 to b340a3a Compare October 31, 2023 13:19
crates/manifest/src/schema/v2.rs Outdated Show resolved Hide resolved
crates/outbound-networking/src/lib.rs Outdated Show resolved Hide resolved
crates/outbound-http/src/host_impl.rs Outdated Show resolved Hide resolved
crates/outbound-networking/src/lib.rs Outdated Show resolved Hide resolved
examples/http-tinygo-outbound-http/spin.toml Show resolved Hide resolved
Signed-off-by: Ryan Levick <ryan.levick@fermyon.com>
@rylev rylev force-pushed the no-more-http-hosts branch from f9f9947 to 6785e96 Compare October 31, 2023 15:44
if !normalized.is_empty() {
terminal::warn!(
"Use of the deprecated field `allowed_http_hosts` - to fix, \
replace the use of `allowed_http_hosts` with `allowed_outbound_hosts = {normalized:?}`",
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: thoughts on reducing to just the following?

Suggested change
replace the use of `allowed_http_hosts` with `allowed_outbound_hosts = {normalized:?}`",
replace with `allowed_outbound_hosts = {normalized:?}`",

Copy link
Contributor

Choose a reason for hiding this comment

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

@vdice maybe

Suggested change
replace the use of `allowed_http_hosts` with `allowed_outbound_hosts = {normalized:?}`",
replace `allowed_http_hosts` with `allowed_outbound_hosts = {normalized:?}`",

so as to be absolutely specific?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If there are no other changes, I might sneak this in to a follow-up PR to avoid having to run CI again, but otherwise 👍

Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

Thanks for working through what must at times have been frustrating feedback. I've not fully grasped the internals of the PR, but it looks good, and the behaviour gives us the long-term plan going forward while making users following older content successful. The ideal outcome.

@itowlson
Copy link
Contributor

I will update the docs to align with this. (Thanks for picking up the templates!)

@rylev rylev merged commit 25de63b into main Oct 31, 2023
9 checks passed
@rylev rylev deleted the no-more-http-hosts branch October 31, 2023 19:45
@itowlson
Copy link
Contributor

@vdice heads up for the JS and Python templates

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants