The explanation below goes hand in hand with the following reproducer: https://github.com/wmedvede/openapi-baseurl-reproducer
Issue:
The serverless workflow backstage-token.sw.yaml tries to access the open api operation
GetEntityByName defined in specs/catalog.yaml by using token propagation.
The given operation is defined with a path like this:
/entities/by-name/{kind}/{namespace}/{name}
However, the corresponding endpoint in the production server is deployed in the following endpoint: http://localhost:8080/api/catalog
And thus, the operation is finally accessed by using http://localhost:8080/api/catalog/entities/by-name/some-kind/some-namespace/some-name
Workflow users expects to configure the workflow like this:
quarkus.rest-client.catalog_yaml.url=http://localhost:8080/api/catalog
However, that configuration doesn't work when we try to use token propagation, i.e., the token is not propagated.
To workaround the issue, we have defined a second workflow backstage-token-fixed.sw.yaml that basically uses the following specs/catalogfixed.yaml with the following path instead:
/api/catalog/entities/by-name/{kind}/{namespace}/{name}
The second workflow is configured like this:
quarkus.rest-client.catalogfixed_yaml.url=http://localhost:8080
Now the token propagation works fine.
Note that if we disable the token propagation, both workflows/openapi documents works fine.
According with https://spec.openapis.org/oas/v3.0.3.html#server-object-example, the paths of the different operations, are relative to the published server urls in the openapi document:
https://spec.openapis.org/oas/v3.0.3.html#server-object-example
e.g.
servers: - url: https://development.gigantic-server.com/api/catalog description: Development server - url: https://staging.gigantic-server.com/api/catalog description: Staging server - url: https://api.gigantic-server.com/api/catalog description: Production server
A configuration like above, indicates that the openapi paths, are published for example in the following root path: https://staging.gigantic-server.com/api/catalog
And thus, following the GetEntityById example, invocations for this example should be like this:
https://staging.gigantic-server.com/api/catalog/entities/by-name/
/{namespace}/{name}
Meaning that the configuration the user did originally should work.
Problem:
The internal matching to determine if an authentication provider must be applied when filtering a request is determined by using only the path present in the operation definition e.g. /entities/by-name/{kind}/{namespace}/{name} that is currently the only information known at build-time. And thus, there are currently no way to do a more elaborated matching that considers the the entry point url e.g. https://development.gigantic-server.com/api/catalog.
To consider situations where the entry points to the api are like these: https://development.gigantic-server.com/api/catalog and comply with the openapi spect we have the following alternatives.
1) if the user wants to configure the endpoint like this:
http://localhost:8080/api/catalog, then, he must also add the corresponding server entry in the open api document.
servers
- urls: http://localhost:8080/api/catalog
and that servers configurations can be used to enrich the current matching. That urls information can be used at build time.
2) we can just add an additional (probably runtime parameter) e.g.
quarkus.openapi-generator.catalog_yaml.baseUrl=/api/catalog and use it to enrich the current filter matching.
other names ->
quarkus.openapi-generator.catalog_yaml.basePath=/api/catalog
quarkus.openapi-generator.catalog_yaml.rootPath=/api/catalog
And internally, to determine a filter matching we can use
/api/catalog + /entities/by-name/{kind}/{namespace}/{name} instead of the only value we can use right now: /entities/by-name/{kind}/{namespace}/{name}
3) any other alternative.