## 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 scheme 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](#application-hierarchy) for more details.

The input to `@useAuth` can be:

- A single security scheme (see options [here](https://github.com/microsoft/typespec/blob/main/packages/http/lib/auth.tsp)).

  ```typespec
  @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.

  ```typespec
  // Use BOTH Auth1 AND Auth2
  @useAuth([Auth1, Auth2])
  ```

- A union of security schemes. This means **one** of the security schemes **must** be used to authenticate this service.

  ```typespec
  // 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.

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

## Available security schemes

Security scheme models can be found in the [TypeSpec HTTP library](https://github.com/microsoft/typespec/blob/main/packages/http/lib/auth.tsp)

### Http Auths

These are authentication methods that use the `Authorization` header. They follow the format `Authorization: <auth-scheme> <authorization-parameters>`

- `auth-scheme`: The authentication scheme that defines how the credentials are encoded.
  :::note
  This value is case insensitive ([rfc7235](https://datatracker.ietf.org/doc/html/rfc7235#section-2.1)). Emitters should handle this accordingly.
  :::
- `authorization-parameters`: Scheme-dependent parameters.

TypeSpec HTTP defines 2 commonly used authentication schemes:

- `BasicAuth` (scheme: Basic)
- `BearerAuth` (scheme: Bearer)

#### `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 followed by a space and a base64-encoded string in the format `username:password`.
For example, to authorize as demo / p@55w0rd the client would send:

```http
Authorization: Basic ZGVtbzpwQDU1dzByZA==
```

In TypeSpec, you would use:

```typespec
@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:

```http
Authorization: Bearer <token>
```

In TypeSpec, you would use:

```typespec
@useAuth(BearerAuth)
```

#### Custom scheme

If your service uses a custom authentication scheme, you can define it as well. For example, if you use a `SharedKey` authentication scheme that would result in the following header:

```http
Authorization: SharedKey <key>
```

you can define it in TypeSpec as follows:

```tsp
model MyCustomAuth {
  type: Http.AuthType.http;
  scheme: "SharedKey";
}
```

### `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 different locations:

In the query string:

```
GET /something?api_key=abcdef12345
```

```typespec
@useAuth(ApiKeyAuth<ApiKeyLocation.query, "api_key">)
```

Or as a request header:

```
GET /something HTTP/1.1
X-API-Key: abcdef12345
```

```typespec
@useAuth(ApiKeyAuth<ApiKeyLocation.header, "X-API-KEY">)
```

Or as a cookie:

```
GET /something HTTP/1.1
Cookie: X-API-KEY=abcdef12345
```

```typespec
@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 protected content from the resource server without sharing their credentials.
For this purpose, an OAuth 2.0 server issues access tokens that client applications can use to access protected resources on behalf of the resource owner.
For more information about OAuth 2.0, see [oauth.net](https://oauth.net) and [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749).

## 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 you want to add a new scheme rather than override, you must re-specify all the parent's security schemes along with the new one.

### Examples

All operations of `MyService` will use `BasicAuth` to authenticate:

```typespec
@useAuth(BasicAuth)
namespace MyService;

op one(): void;
op two(): void;
```

In this example, `one` will use `ApiKey` auth and `two` will use `Basic` auth:

```typespec
@useAuth(BasicAuth)
namespace MyService;

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

Here, `one` will accept either `ApiKey` or `Basic` auth, while `two` will only accept `Basic` auth:

```typespec
@useAuth(BasicAuth)
namespace MyService;

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

## OAuth2 Scopes

The `OAuth2` security scheme can require specific scopes that must be granted to the OAuth2 token to access the operations the security scheme applies to.
When different operations need 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:

```tsp
@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;
```