Requests for comment/Service-oriented architecture authentication

Problem statement
With many more entry points and the need for inter-service authentication, a service-oriented architecture requires a stronger authentication system.

Goals

 * single sign-on support
 * support a relatively timely revocation of rights (minutes)
 * minimize the risk & impact of exploits:
 * confused deputy
 * most services should not have access to sensitive user information (password hashes etc)
 * be efficient for high request volumes (APIs)
 * no synchronous checking with other services required for common requests (reads etc)
 * follow best security guidelines, use established standards & existing implementations
 * support derivative and asynchronous requests like link updates
 * but don't allow them directly

Context
MediaWiki currently provides several authentication and authorization checks for users. It provides:
 * Account creation and autocreation
 * Authentication (password, or plugin based)
 * Authorization / session management
 * Sets up the appropriate User object (e.g., $wgUser) for each request, before MediaWiki processes the request
 * MediaWiki uses the User object for most code that determine authorization
 * The User object tracks if the user has been blocked, and can validate anti-CSRF tokens for the user's session
 * Logout (destroy the session)

This RFC is primarily about the authorization / session management aspect. Services need to identify the user making the call, and determine the service's authorization for that user. The desire is to be able to do this without sharing php's session cache, or getting the User object out of memcache.

For Requests_for_comment/Content_API, the proposal is for services to share the same domain, so we can use an http-only/secure cookie to identify the user to the service.

OpenID connect / OAuth2 + Bearer tokens

 * All authenticated traffic uses TLS
 * Authentication service is only service that has access to sensitive user information
 * Client authentication
 * Normal browser auth / our domains: Bearer token is set in HTTP-only cookie (instead of session id)
 * Cross-domain: Client follows the normal OpenID connect token request flow with auth service
 * retrieves time-limited signed Bearer token
 * token encodes common access rights like 'read article' (in signed JWT)
 * Client sends token with each request (SPDY can make sure it only goes over the wire once)
 * Most backend services have no special rights; they merely forward the user-provided token to other services
 * Checking happens at the lowest possible layer to avoid multiple entry point issues. Example: storage service
 * Common requests like read only require a signature and timestamp check
 * Less common requests require calls back into auth service to establish rights
 * CSRF tokens for state-changing operations provided and verified by the auth service on behalf of backends (storage service for example)
 * performance not as critical as those operations are rare compared to reads
 * Authenticate derivative requests when enqueuing them, based on per-queue ACLs. Once authenticated & enqueued, an additional signed assertion added by the queue removes the auth timeout, so that jobs will be able to complete in the background. Ideally such jobs are idempotent and depend on a primary authenticated request having gone through. This would make them relatively harmless & avoid the need for additional protection against making those requests directly beyond not exposing them publicly.

OpenID connect is used by: PayPal, Microsoft, Salesforce, Google, Deutsche Telekom, mobile carriers (GSMA) etc