Home

Awesome

oz Logo

Oz is a web authorization protocol based on industry best practices. Oz combines the Hawk authentication protocol with the Iron encryption protocol to provide a simple to use and secure solution for granting and authenticating third-party access to an API on behalf of a user or an application.

Protocol version: 5.0.0 (Same as v1.0.0 but moved the expired ticket indicator from a header attribute to the error payload).

Build Status

Table of Content

Protocol

Oz builds on the well-understood concepts behind the OAuth protocol. While the terminology has been updated to reflect the common terms used today when building applications with third-party access, the overall architecture is the same. This document assumes the reader is familiar with the OAuth 1.0a protocol workflow.

Workflow

  1. The application uses its previously issued Hawk credentials to authenticate with the server and request an application ticket. If valid, the server issues an application ticket.
  2. The application directs the user to grant it authorization by providing the user with its application identifier. The user authenticates with the server, reviews the authorization grant and its scope, and if approved the server returns an rsvp.
  3. The user returns to the application with the rsvp which the application uses to request a new user-specific ticket. If valid, the server returns a new ticket.
  4. The application uses the user-ticket to access the user's protected resources.

Application

Oz is an application-to-server authorization protocol. This means credentials are issued only to applications, not to users. The method through which users authenticate is outside the scope of this protocol.

The application represents a third-party accessing protected resource on the server. This third-party can be another server, a native app, a single-page-app, or any other application using web resources. The protected resources can be under the control of the application itself or under the control of a user who grants the application access.

Each application definition includes:

Applications must be registered with the server prior to using Oz. The method through which applications register is outside the scope of this protocol. When an application registers, it is issued a set of Hawk credentials. The application uses these credentials to obtain an Oz ticket.

The application Hawk credentials include:

The Hawk protocol supports two Oz-specific header attributes which are used for authenticating Oz applications (app and dlg).

User

Applications act on behalf of users. Users are usually people with protected resources on the server who would like to use the application to access those protected resources. For the purpose of the Oz protocol, each user must have a unique identifier which is used by the protocol to record access rights. The method through which users are registered, authenticated, and managed is beyond the scope of this protocol.

Ticket

An Oz ticket is a set of Hawk credentials used by the application to access protected resources. Just like any other Hawk credentials, the ticket includes:

However, unlike most Hawk credential identifiers, the Oz identifier is an encoded Iron string which when decoded contains:

When a ticket is generated and sent to the application by the server, the response includes all of the above properties with the exception of ext which is included but only with the content of ext.public if present.

The ticket expiration can be shorter than the grant expiration in which case, the application can reissue the ticket. This provides the ability to limit the time credentials are valid but allowing grants to have longer lifetime.

When tickets are reissued, they can be constrained to less scope or duration, and can also be issued to another application for access delegation.

Grant

A grant is the authorization given to an application by a user to access the user's protected resources. Grants can be persisted in a database (usually to support revocation) or can be self describing (using an encoded identifier). Each grant contains:

Scope

Scope is an array of strings, each represents an implementation-specific permission on the server. Each scope string adds additional permissions to the application (i.e. ['a', 'b'] grants the application access to both the 'a' and 'b' rights, individually).

Each application has a default scope which is included in the tickets issued to the application unless the grant specifies a subset of the application scope. Applications cannot be granted scopes not present in their default set.

Rsvp

When the user authorizes the application access request, the server issues an rsvp which is an encoded string containing the application identifier, the grant identifier, and an expiration.

API

The Oz public API is offered as a full toolkit to implement the protocol as-is or to modify it to fit custom security needs. Most implementations will only need to use the endpoints functions methods and the ticket.rsvp() method directly.

Shared objects

app object

An object describing an application where:

grant object

An object describing a user grant where:

ticket response

An object describing a ticket and its public properties:

Oz.client

Utilities used for making authenticated Oz requests.

Oz.client.header(uri, method, ticket, [options])

A convenience utility to generate the application Hawk request authorization header for making authenticated Oz requests where:

new Oz.client.Connection(options)

Creates an oz client connection manager for easier access to protected resources. The client manages the ticket lifecycle and will automatically refresh the ticken when expired. Accepts the following options:

await connection.request(path, ticket, options)

Requests a protected resource where:

Return value: { result, code, ticket } where: - result - the requested resource (parsed to object if JSON). - code - the HTTP response code. - ticket - the ticket used to make the request (may be different from the ticket provided when the ticket was expired and refreshed). - throws request errors.

await connection.app(path, options)

Requests a protected resource using a shared application ticket where:

Return value: { result, code, ticket } where: - result - the requested resource (parsed to object if JSON). - code - the HTTP response code. - ticket - the ticket used to make the request (may be different from the ticket provided when the ticket was expired and refreshed). - throws request errors.

Once an application ticket is obtained internally using the provided hawk credentials in the constructor, it will be reused by called to connection.app(). If it expires, it will automatically refresh and stored for future usage.

await connection.reissue(ticket)

Reissues (refresh) a ticket where:

Return value: the reissued ticket.

Oz.endpoints

The endpoint methods provide a complete HTTP request handler implementation which is designed to be plugged into an HTTP framework such as hapi. The scarecrow plugin provides an example of how these methods integrate with an existing server implementation.

Endpoints options

Each endpoint method accepts a set of options.

encryptionPassword

A required string used to generate the ticket encryption key. Must be kept confidential. The string must be the same across all Oz methods and deployments in order to allow the server to parse and generate compatible encoded strings.

The encryptionPassword value is passed directly to the Iron module which supports additional inputs for pre-generated encryption and integrity keys as well as password rotation.

loadAppFunc

The application lookup method using the signature async function(id) where:

loadGrantFunc

The grant lookup method using the signature async function(id) where:

await endpoints.app(req, payload, options)

Authenticates an application request and if valid, issues an application ticket where:

Return value: a ticket response object or throws an error.

await endpoints.reissue(req, payload, options)

Reissue an existing ticket (the ticket used to authenticate the request) where:

Return value: a ticket response object or throws an error.

await endpoints.rsvp(req, payload, options)

Authenticates an application request and if valid, exchanges the provided rsvp with a ticket where:

Return value: a ticket response object or throws an error.

Oz.hawk

Provides direct access to the underlying Hawk module.

Oz.scope

Scope manipulation utilities.

Oz.scope.validate(scope)

Validates a scope for proper structure (an array of unique strings) where:

Returns an Error is the scope failed validation, otherwise null for valid scope.

Oz.scope.isSubset(scope, subset)

Checks whether a scope is a subset of another where:

Returns true if the subset is fully contained with scope, otherwise `false.

Oz.server

Server implementation utilities.

await Oz.server.authenticate(req, encryptionPassword, options)

Authenticates an incoming request using Hawk and performs additional Oz-specific validations where: Authenticates an application request and if valid, issues an application ticket where:

Return value: { ticket, artifacts } or throws an error where: - ticket - the decoded ticket response object. - artifacts - Hawk protocol artifacts.

Oz.ticket

Ticket issuance, parsing, encoding, and re-issuance utilities.

Ticket options

The following are the supported ticket parsing and issuance options passed to the corresponding ticket methods. Each endpoint utilizes a different subset of these options but it is safe to pass one common object to all (it will ignore unused options):

await ticket.issue(app, grant, encryptionPassword, options)

Issues a new application or user ticket where:

Return value: a ticket response object.

await ticket.reissue(parentTicket, grant, encryptionPassword, options)

Reissues a application or user ticket where:

Return value: a ticket response object or throws an error.

await ticket.rsvp(app, grant, encryptionPassword, options)

Generates an rsvp string representing a user grant where:

Return value: the rsvp string or throws an error.

await ticket.generate(ticket, encryptionPassword, options)

Adds the cryptographic properties to a ticket and prepares the response where:

Return value: the completed ticket response object or throws an error.

await ticket.parse(id, encryptionPassword, options)

Decodes a ticket identifier into a ticket response where:

Return value: a ticket response object or throws an error.

Security Considerations

The greatest sources of security risks are usually found not in Oz but in the policies and procedures surrounding its use. Implementers are strongly encouraged to assess how this protocol addresses their security requirements. This section includes an incomplete list of security considerations that must be reviewed and understood before deploying Oz on the server. Most of these security considerations are the same as the security considerations for Hawk, and many of the protections provided in Hawk depend on whether or not they are used and how they are used.

Ticket and Application Hawk Credentials Transmission

Oz does not provide any mechanism for obtaining or transmitting the set of shared Hawk credentials for the application. Any mechanism the application uses to obtain the Hawk credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.

Plaintext Storage of Ticket and Application Hawk Credentials

The ticket keys and application Hawk keys in Oz function the same way passwords do in traditional authentication systems. In order to compute the request MAC, the server must have access to the key in plain-text form. This is in contrast, for example, to modern operating systems, which store only a one-way hash of user credentials.

If an attacker were to gain access to these keys—or worse, to the server's database of all such keys—he or she would be able to perform any action on behalf of the user. Accordingly, it is critical that servers protect these keys from unauthorized access.

Entropy of Keys

Unless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request MAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to assign ticket keys and application Hawk keys that are long and random enough to resist such attacks for at least the length of time that the ticket credentials or the application Hawk credentials are valid.

For example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force attack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution and use the longest key reasonable.

It is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high quality. Many PRNG implementations generate number sequences that may appear to be random, but nevertheless exhibit patterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use cryptographically secure PRNGs to avoid these problems.

Application Redirect URI

If the server redirects the RSVP to the application, the server should require a redirect URI for the application when the application is registered. This redirect URI would be used by the server to redirect back to the application with the RSVP after the user approves the grant. If the application supplies the redirect URI to the server and the server uses only this redirect URI to send the RSVP to the application, it is possible for an attacker to intercept the request from the application to server, change the supplied redirect URI to steal the RSVP, and exchange the RSVP for a user ticket if the application ticket credentials or application Hawk credentials were also stolen by the attacker. Additionally, the server requiring the registration of a redirect URI of an application adds an extra layer of security if the server redirects the RSVP to the application, because it limits what the attacker can do if he or she steals the application ticket credentials or application Hawk credentials.