Cross Container Data Requests

Proposer: Chris Cole, Myspace

This proposal seeks to define a mechanism for gadgets running in one container to invoke data endpoints existing in another container.  It also allows for defining multiple signing mechanisms for cases where a gadget may have to talk to APIs secured with different OAuth keys.

Use Cases

Use Case 1:

A container executing on a non-affiliated site wishes to allow gadgets executing in its environment to access social APIs from an external social network, like Myspace or Orkut by using strong data tags (ex: <os:PeopleRequest >)

Use Case 2:

A container needs to access a third-party endpoint that is secured with an oauth key other than the main app's oauth key.  The gadget may embed an encrypted set of credentials to use for signing.

Proposal Details

Calls to arbitrary API endpoints are currently facilitated in gadgets either through the <os:HttpRequest> tag or the gadgets.io.makeRequest Javascript API.  While these function for some limited cases, they do not properly allow for management of multiple API keys or OAuth signatures.  Rather, they only allow for using the main OAuth credentials of the gadget or no security at all.

This proposal defines a mechanism to reference and use multiple credentials to different API endpoints within the gadget file in a way that they can be used to invoke both OpenSocial and non-OpenSocial API endpoints.  This is done by defining a serviceProvider and allowing data tags to specify a @serviceProvider attribute that ties to the apiProvider key.  The container then uses the supplied security credentials, uriBase - if applicable, and signing mechanism when resolving the request.  The basic service provider details MAY be specified in the gadget XML file or specified out of band, but the container MUST specify actual security keys out of band from the gadget XML and all referenced files such that the keys may not be compromised.

Actual implementation of out of band key management is left to the containers. One sample implementation would be to provide a secure management console to developer for supplying the service provider keys.  They keys would be registered with the app and under a matched serviceProvider identifying key.  The serviceProvider identifying key is matched by the container during request processing to retrieve the additional credentials to secure the request.

Examples use the simple gadget syntax for ease of understanding.

ex:

Sample cross-container request
<Module>
<ModulePrefs>
  <Require feature="service-providers" >
    <os:serviceProvider key="fooNetwork" authz="oauth2">
     <uriBasePath>http://fooNet.com/apis/v2/</uriBasePath>
    </os:apiProvider>
  </Require>
</ModulePrefs>
<Data>

<os:PeopleRequest key="incontainerPeople" />
<os:PeopleRequest key="fooPeople" serviceProvider="fooNetwork" />
<os:HttpRequest key="arbitraryFoo" serviceProvider="fooNetwork"
href="http://fooNet.com/exampleElse/proprietaryStuff" />
</Data>
<Content>
I got a proprietary answer of ${arbitraryFoo.SpecialValue} from that endpoint.
There are ${incontainerPeople.totalResults} people defined in this container.
There are ${fooPeople.totalResults} people defined on fooNet.

</Content>
</Module>


Deprecated

The section are being deprecated as part of this proposal:

From Proxied Content: http://opensocial-resources.googlecode.com/svn/spec/2.0/Core-Gadget.xml#ProxiedContent

and from gadgets.io.makeRequest http://opensocial-resources.googlecode.com/svn/spec/2.0/Core-Gadget.xml#rfc.section.12.2.1.3.4

OAUTH_SERVICE_NAME -> This is being replaced with the more generic serviceProvider value to handle both multiple OAuth versions and non-OAuth credential mechanisms

Syntax

This feature is tied to the dataProvider feature and is specified with a <Require> element in the <ModulePrefs> section.

<os:serviceProvider> tag

The <os:apiProvider> tag defines a distinct provider that may be used in place of the Container's default provider.  This tag is used to define security credentials and how they're encrypted, base location of the API server, if the external site is a Social API Server as defined in the spec, and a key to identify the api provider.

@key

The @key attribute defines a unique identifier for this provider that can be referenced by other data tags.

@authz

The authorization mechanism to be used when invoking an endpoint using this provider.  This should include values available to gadget.io.makeRequest and <os:HttpRequest> mechanisms.

uriBasePath

The API base uri for conforming Core API servers as defined in the spec:
http://opensocial-resources.googlecode.com/svn/spec/1.1/Core-API-Server.xml#REST-Base-Path
This URI is used to construct the appropriate path to standard strongly-defined endpoints.  This allows strongly-defined data tags to be used against an external provider.

Data tag usage

Data tags may use this by specifying the @serviceProvider attribute with the apiProvider key as the value.  In the case of arbitrary endpoints referenced with the <os:HttpRequest> tag, only the authorization mechanism will be used.  The tag must still specify a fully qualified URI in the @href value.  For strongly-defined data tags, like <os:PeopleRequest>, the service provider referenced with the @serviceProvider attribute will utilize the defined uriBasePath value and partial path defined as the REST-URI-Fragment value. 

In the case of an os:PeopleRequest, this would be defined as $

Unknown macro: {uriBasePath}

/people per the spec http://opensocial-resources.googlecode.com/svn/spec/1.1/Social-API-Server.xml#People-Service-GetPerson

gadgets.io.makeRequest

The client-side gadgets.io.makeRequest may also utilize a service provider by adding the SERVICE_PROVIDER parameter and desired identifying key as part of the opt_params to the makeRequest call.

Final Notes

This proposal supersedes the previous mechanism for specifying oauth credentials as unencrypted plain text embedded in the gadget.  This feature was defined in the 0.9 specification as below, but was written out of the 1.0 specification.

Credential support was defined as below:

  • @oauth_request_token_secret 
    Unknown macro: {string}
      Secret associated with the pre-approved request token.

http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/OpenSocial-Data-Pipelining.html#HttpRequest

In the 1.1 spec, these attributes have been removed.

http://opensocial-resources.googlecode.com/svn/spec/1.1/Core-Gadget.xml#HttpRequest

As identified above, the OAuth section of ModulePrefs and the usage of OAUTH_SERVICE_NAME in proxied content and gadgets.io.makeRequest are being deprecated.
From Proxied Content: http://opensocial-resources.googlecode.com/svn/spec/2.0/Core-Gadget.xml#ProxiedContent

and from gadgets.io.makeRequest http://opensocial-resources.googlecode.com/svn/spec/2.0/Core-Gadget.xml#rfc.section.12.2.1.3.4

OAUTH_SERVICE_NAME -> This is being replaced with the more generic serviceProvider value to handle both multiple OAuth versions and non-OAuth credential mechanisms