There are various ServiceProviders that do X, Y, and/or Z. A valid SP
must do X and Y, but Z is optional. A user generally picks one SP (or
hosts their own) and uses that exclusively. The SP needs to provide
authenticated API endpoints for each of the actions it provides,
e.g. GET /api/x
, POST /api/y
.
An Application needs to interact with a user's SP. Discovery of the user's SP happens via WebFinger or some intermediary (e.g., explicitly asking the user and storing preference, like http://www.subtome.com/? Any other suggestions?).
Once the user's SP has been determined, the Application needs to know how to communicate with the SP (without going through the intermediary) and what methods are supported. What is the best way for an application to figure out the supported API endpoints of a ServiceProvider?
I am working on federation for "OpenBadge Backpacks". I want users to be able to host their backpack anywhere and to have issuers be able to interact with a user's specified backpack using a generic interface (rather than having issuers figure out/dictate/hardcode which backpacks they support).
Ideally a user should be able to say to the issuer "My backpack is at
https://example.org" (or predefine this so it's somehow discoverable)
and the issuer should be able to communicate with that backpack without
having to apply conditional logic specific to example.org
.
The specification for ServiceProviders could say "You MUST have your API
endpoints at /api/x, /api/y and /api/y". Applications/libraries would
hardcode relative paths and route actions to the ServiceProviders based
on <origin>+<relative path for action>
.
- This seems too restrictive for ServiceProviders. I could see an SP wanting the flexibility to choose their API root.
- Capabilities would have to be figured out by trial & error.
The specification could require an description file, e.g.
{
"name" "Example ServiceProvider",
"apiRoot": "https://api.example.org",
"capabilities": ["x", "y"]
}
The descriptive file should be discoverable by scanning for a <link rel="serviceprovider:api" href="<path-to-resource>">
and have that file be somewhere in the HTTP response to
GET / HTTP/1.1
Host: example.org
- What's the appropriate
rel
for this? - Requires the Application to parse HTML (though they could "cheat" with a regexp)
Same descriptive file as above, but the location would be standardized at a .well-known/
location (see RFC 5758).
- Appendix B of RFC 5758 claims that well-known locations are "bad for the web" and I don't know why.
Local storage should be an option, but for my specific use case we need hosted providers. Many of our users access the internet mainly through public terminals, so we can't guarantee data integrity between sessions.
I'm open to entirely different suggestions of how to solve this problem. I'm partial to the idea of a "descriptive file" that states a ServiceProvider's capabilities becasue I think it's nicely extensible.
There's also an inherent assumption that the API root is the only potential difference between ServiceProviders, and that everything below that is uniform. I think it's acceptable to specify this, mainly because I think not doing that would increase complication be an unacceptable amount, but I'm open to discussion on that front as well.
Oh, and re: RFC 5785, Appendix B, "Aren't well-known locations bad for the Web?"
I think the bad mostly consists of:
.well-known
. That's a consequence of giving up URL opacity, but it's a usability tradeoff for discovery without asking users to carry URLs around..well-known
means that it at least doesn't infect the rest of your URL-space. (ie. that's the "sandbox" part)That's why I say I'm lazy when I like Solution 1. I can think less about flexibility and make more demands on service providers' URL-space, but that's rather rude.