Skip to content

Commit

Permalink
Restructuring action page content checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
S3Prototype committed Feb 13, 2025
1 parent 2fac32c commit d39011b
Show file tree
Hide file tree
Showing 8 changed files with 792 additions and 66 deletions.
150 changes: 137 additions & 13 deletions docs/traffic-policy/actions/add-headers.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,142 @@
import ActionBehavior from "/traffic-policy/actions/add-headers/behavior.mdx";
import ActionConfig from "/traffic-policy/actions/add-headers/config.mdx";
import ActionExamples from "/traffic-policy/actions/add-headers/examples/index.mdx";
import ActionOverview from "/traffic-policy/actions/add-headers/index.mdx";
import ActionVariables from "/traffic-policy/actions/add-headers/variables.mdx";
import ActionVariablesDescription from "/traffic-policy/common/action-variables-description.mdx";
---
title: Add Headers
---

## Add Headers
import ConfigExample from "/src/components/ConfigExample.tsx";
import { Config, ConfigItem } from "/src/components/ConfigTable.tsx";

<ActionOverview />
<ActionConfig />
<ActionBehavior />
<ActionExamples />
The `add-headers` [Traffic Policy](/traffic-policy/) action enables you to add headers to an HTTP request before it is sent upstream or an HTTP response before it is sent back to the client.

## Use cases

Using `add-headers` enables you to:

- **Enrich your upstream service**: Add rich contextual features to your upstream services such as language localization, regional pricing, and more by adding [geolocation data](/traffic-policy/variables/ip-intel#client-ip-geo-location) to the headers of incoming requests.
- **Authentication**: Secure upstream services by using Traffic Policy to add authentication headers to requests.
- **Debugging**: Add headers to requests and responses to help with debugging and monitoring of your services.

## Configuration Reference

- [**Supported Phases**](/traffic-policy/concepts/phases/)
- [`on_http_request`](/traffic-policy/concepts/phases/#on_http_request)
- [`on_http_response`](/traffic-policy/concepts/phases/#on_http_response)
- **Type**
- `add-headers`

### Fields

<Config>
<ConfigItem title="headers" type="object" cel={true}>
<p>Map of header key to header value to be added.</p>
<p>Minimum `1`, Maximum `10`.</p>
<p>
Supports [CEL Interpolation](/traffic-policy/concepts/cel-interpolation)
in header values.
</p>
</ConfigItem>
</Config>

Here's an example `add-headers` action configured to add a header with a string and a header with an IP Intelligence Variable.

```yaml
actions: [
{
type: "add-headers",
config: {
"x-example-header": "example-value",
"x-example-header2": "${endpoint.id}"
},
},
],
```

See [the example on this page](#example) for a full traffic policy using this action.

## Behavior

When configured in the `on_http_request` phase, this action will add the specified headers to incoming http requests before reaching the upstream server. When
configured in the `on_http_response` phase, the specified headers are added to the http response from the upstream server.

### Addition Only

This action will only add headers to the request or response. If the header already exists
it will append another header with the same key unless it is the `host` header,
see [Special Cases](#special-cases).

To replace or remove headers use the [`remove-headers`](/docs/traffic-policy/actions/remove-headers) action then
add the header with the desired value.

### Case Sensitivity

Header keys added through this action are normalized to lowercase per the [HTTP/2 specification](https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2).

### Ordering

Since actions are run in the order they are specified, to modify headers that have been added by other actions you must place this action
after them in your traffic policy document.

### Limitations

- Adding the `host` header override the existing value instead of appending another header.
- You may not add or remove the `user-agent` header.
- You may not use this action to add the `ngrok-skip-browser-warning` header to skip the ngrok browser warning on free accounts. For more information, check out the [free plan limits guide](http://localhost:3000/docs/guides/limits/#why-is-there-an-interstitial-in-front-of-my-html-content).

### Action Result Variables

<ActionVariablesDescription />
<ActionVariables />
<Config>
<ConfigItem title="actions.ngrok.add_headers.headers_added" type="object">
<p>Map of headers that were added by the action.</p>
</ConfigItem>
</Config>

## Example

### Adding headers to an HTTP response

The following [Traffic Policy](/docs/http/traffic-policy/)
configuration will add headers to the response from the upstream service when the method is `GET` and the URL starts with `/status/200`.

<ConfigExample
snippetText={null}
showLineNumbers={true}
yamlMetastring="{6-10}"
jsonMetastring="{8-16}"
config={{
on_http_response: [
{
expressions: [
'req.method == "GET" && req.url.path.startsWith("/status/200")',
],
actions: [
{
type: "add-headers",
config: {
headers: {
"x-custom-header": "my-custom-value",
"x-string-interpolation-example": "started at ${conn.ts.start}",
},
},
},
],
},
],
}}
/>

For this example, we are assuming that ngrok is pointing at the upstream service
https://httpbin.org and we will be adding two headers:

- `x-custom-header` with the value `my-custom-value`
- `x-string-interpolation-example` with the value `started at ${conn.ts.start}` to demonstrate the use of CEL interpolation to include the request connection start time.

#### Example Request

```shell
$ curl -i https://httpbin.ngrok.app/status/200
```

```http
HTTP/2 200 OK
x-custom-header: my-custom-value
x-string-interpolation-example: started at 2024-07-13T00:10:16Z
```
156 changes: 143 additions & 13 deletions docs/traffic-policy/actions/basic-auth.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,148 @@
import ActionBehavior from "/traffic-policy/actions/basic-auth/behavior.mdx";
import ActionConfig from "/traffic-policy/actions/basic-auth/config.mdx";
import ActionExamples from "/traffic-policy/actions/basic-auth/examples/index.mdx";
import ActionOverview from "/traffic-policy/actions/basic-auth/index.mdx";
import ActionVariables from "/traffic-policy/actions/basic-auth/variables.mdx";
import ActionVariablesDescription from "/traffic-policy/common/action-variables-description.mdx";
---
title: Basic Auth
---

## Basic Auth
import ConfigExample from "/src/components/ConfigExample.tsx";
import { Config, ConfigItem } from "/src/components/ConfigTable.tsx";

<ActionOverview />
<ActionConfig />
<ActionBehavior />
<ActionExamples />
The `basic-auth` Traffic Policy action enables you to enforce HTTP Basic Auth
on your endpoints. Requests with a valid username and password will be sent to
your upstream service, all others will be rejected with a `401 Unauthorized` response.

### Configuration Reference

This is the [Traffic Policy](/docs/traffic-policy/) configuration
reference for this action.

#### Supported Phases

`on_http_request`

#### Type

`basic-auth`

#### Configuration Fields

<Config>
<ConfigItem title="credentials" type="array of strings" required={true}>
<p>A list of up to 10 allowed <code>username:password</code> credential pairs.</p>
<p>Password must be at least <code>8</code> characters and no more than <code>128</code> characters.</p>
</ConfigItem>

<ConfigItem title="realm" type="string" required={false}>
<p>The HTTP realm of the request as per <a href="https://datatracker.ietf.org/doc/html/rfc7235">RFC 7235</a>.</p>
<p>Default is <code>ngrok</code>.</p>
</ConfigItem>

<ConfigItem title="enforce" type="bool" required={false}>
<p>Default <code>true</code>. If <code>false</code>, continue to the next action even if basic authentication failed. This is useful for handling fall-through, debugging, and testing purposes.</p>
</ConfigItem>

</Config>

### Behavior

The **basic-auth** action enforces HTTP Basic Authentication on incoming requests, as specified
in [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235). When a request is received, the action
verifies the request by validating against a known set of `user:password` credentials. If the
verification is successful, the action allows the request to continue through the action chain and
finally to your application; if verification fails, the request will be terminated with a
`401 Unauthorized` response.

#### Additional Restrictions

You can specify up to 10 `username:password` pairs. The password must be at least
8 characters and no more than 128 characters. Including multiple colons in the `username:password`
pair will result in the first colon being treated as the delimiter between the username and password.
Realm cannot exceed 128 characters, and cannot contain non-ASCII characters.

#### Verification Process

- **HTTP Authentication**: The action validates incoming HTTP requests to confirm they contain the required `Authorization` header, in the form of `Authorization: Basic <credentials>`, where `<credentials>` is the Base64 encoding of username and password joined by a single colon `:`.
- **Request Handling**: If the authentication is successful, the request is forwarded to the next action. If the authentication fails, it will return to user a `401` response, which will prompt the user to provide a correct set of credentials.
- **Configurable Enforcement**: By default, authentication failures result in 401s. However, setting `enforce: false` allows unauthenticated requests to proceed, while logging the authentication result. This option is for debugging and testing.

#### Secret Handling and Encryption

All secrets used for basic authentication are encrypted at config validation. When ngrok processes a request, the secret is decrypted.

### Examples

The following [Traffic Policy](/docs/http/traffic-policy/)
configuration is an example configuration of the `basic-auth` action.

#### Example Traffic Policy Document

<ConfigExample
snippetText={null}
showLineNumbers={true}
jsonMetastring="{5-51}"
yamlMetastring="{4-28}"
config={{
on_http_request: [
{
actions: [
{
type: "basic-auth",
config: {
realm: "sample-realm",
credentials: ["user:password1", "admin:password2"],
enforce: true,
},
},
{
type: "custom-response",
config: {
status_code: 200,
headers: { "content-type": "text/plain" },
content: "Successfully Authenticated!",
},
},
],
},
],
}}
/>

#### Example Request

First, base64 encode the `username:password` pair.
`user:password1` becomes `dXNlcjpwYXNzd29yZDE=`

```shell
$ curl --request GET \
--url http://example-api.ngrok.app/ \
--header 'Authorization: Basic dXNlcjpwYXNzd29yZDE=`'
```

```http
HTTP/2 200 OK
content-type: text/html
Successfully Authenticated!
...
```

In this example, we are sending a request to our API with a valid set of credentials in
the `Authorization` header with the `Basic` prefix and getting back a `200 OK`
response.

You can try it without the header, and you will receive a `401 Unauthorized` prompt
instead.

### Action Result Variables

<ActionVariablesDescription />
<ActionVariables />
<Config>
<ConfigItem title="actions.ngrok.basic_auth.credentials.presented" type="bool" required={false}>
<p>Whether there were Basic Auth credentials presented in the Authorization header.</p>
</ConfigItem>

<ConfigItem title="actions.ngrok.basic_auth.credentials.username" type="string" required={false}>
<p>The username of the credentials presented.</p>
</ConfigItem>

<ConfigItem title="actions.ngrok.basic_auth.credentials.authorized" type="bool" required={false}>
<p>Whether the presented basic auth credentials were authorized for this request.</p>
</ConfigItem>

</Config>
Loading

0 comments on commit d39011b

Please sign in to comment.