Skip to content

Authentication

Configure

Authentication can be configured using the @useAuth decorator on a service namespace, sub-namespace, interface or operation.

The @useAuth decorator takes as input the security to apply for all operations contained in the type. If another @useAuth was specified on a parent type the new one will override the value of the parent. See application hierarchy

The input can be a:

  • A single security scheme (see options here).

    @useAuth(Auth1)
  • A tuple of security schemes. This creates a security group and means all the security schemes in the group must be used together to authenticate this service.

    // Use BOTH Auth1 or Auth2
    @useAuth([Auth1, Auth2])
  • A union of security schemes. This means one of the security schemes must be used to authenticate this service.

    // Use EITHER Auth1 or Auth2
    @useAuth(Auth1 | Auth2)
  • A union of security schemes and tuples representing security groups. This means one of the security groups or security schemes must be used to authenticate this service.

    // Use EITHER (Auth1 AND Auth2) OR Auth3
    @useAuth([Auth1, Auth2] | Auth3)

Available security schemes

Models can be found in https://github.com/microsoft/typespec/blob/main/packages/http/lib/auth.tsp

BasicAuth

Basic authentication is a simple authentication scheme built into the HTTP protocol. The client sends HTTP requests with the Authorization header that contains the word Basic word followed by a space and a base64-encoded string username:password. For example, to authorize as demo / p@55w0rd the client would send

Authorization: Basic ZGVtbzpwQDU1dzByZA==
@useAuth(BasicAuth)

BearerAuth

Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. The name “Bearer authentication” can be understood as “give access to the bearer of this token.” The bearer token is a cryptic string, usually generated by the server in response to a login request. The client must send this token in the Authorization header when making requests to protected resources:

Authorization: Bearer <token>
@useAuth(BearerAuth)

ApiKeyAuth<TLocation extends ApiKeyLocation, TName extends string>

An API key is a token that a client provides when making API calls. The key can be sent in the query string:

GET /something?api_key=abcdef12345
@useAuth(ApiKeyAuth<ApiKeyLocation.query, "api_key">)

or as a request header

GET /something HTTP/1.1
X-API-Key: abcdef12345
@useAuth(ApiKeyAuth<ApiKeyLocation.header, "X-API-KEY">)

or as a cookie

GET /something HTTP/1.1
Cookie: X-API-KEY=abcdef12345
@useAuth(ApiKeyAuth<ApiKeyLocation.cookie, "X-API-KEY">)

OAuth2Auth<TFlows extends OAuth2Flow[]>

OAuth 2.0 is an authorization protocol that gives an API client limited access to user data on a web server. OAuth relies on authentication scenarios called flows, which allow the resource owner (user) to share the protected content from the resource server without sharing their credentials. For that purpose, an OAuth 2.0 server issues access tokens that the client applications can use to access protected resources on behalf of the resource owner. For more information about OAuth 2.0, see oauth.net and RFC 6749.

Application hierarchy

The @useAuth decorator can be used on a service namespace, sub-namespace, interface or operation. The security scheme specified will be applied to all operations contained in the type. A child type with a @useAuth will override the security scheme of the parent type. If the goal is to append a new scheme, you must re-specify the security schemes on the parent and add the new scheme.

Examples

All operations of MyService will use BasicAuth to authenticate

@useAuth(BasicAuth)
namespace MyService;
op one(): void;
op two(): void;

one will use ApiKey auth and two will use the Basic auth.

@useAuth(BasicAuth)
namespace MyService;
@useAuth(ApiKeyAuth<ApiKeyLocation.query, "api_key">)
op one(): void; // Use ApiKey only
op two(): void; // Use BasicAuth

one will use ApiKey or Basic auth and two will use the Basic auth.

@useAuth(BasicAuth)
namespace MyService;
@useAuth(BasicAuth | ApiKeyAuth<ApiKeyLocation.query, "api_key">)
op one(): void; // Use ApiKey only
op two(): void; // Use BasicAuth

OAuth2 Scopes

The OAuth2 security scheme can have a list of scopes that must be granted to the OAuth2 token to be able to use the operations the security scheme applies to. When different operations have different scopes, you will likely want to create a template that allows providing OAuth scopes without having to respecify the other properties of the security scheme:

@useAuth(MyOAuth2<["read"]>)
namespace DemoService;
alias MyOAuth2<Scopes extends string[]> = OAuth2Auth<
[
{
type: OAuth2FlowType.implicit;
authorizationUrl: "https://api.example.com/oauth2/authorize";
refreshUrl: "https://api.example.com/oauth2/refresh";
}
],
Scopes
>;
// Use OAuth2 with the "read" scope
op list(): string[];
// Use OAuth2 with the "read" scope or no authentication at all
@useAuth(MyOAuth2<["read"]> | NoAuth)
op read(): string;
// Use OAuth2 with the "write" scope
@useAuth(MyOAuth2<["write"]>)
op write(value: string): void;
// Use OAuth2 with the "delete" scope
@useAuth(MyOAuth2<["delete"]>)
op delete(value: string): void;