Skip to content

feat: add inflight rate limiting documentation and improve tooling #2255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ SHELL=/bin/bash -euo pipefail
export GO111MODULE := on
export PATH := .bin:${PATH}

.PHONY: help
help: ## Show this help message
@echo "Available targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}'

.PHONY: format
format: node_modules
format: node_modules ## Format code using prettier
npm exec -- prettier --write .

.PHONY: format-licenses
format-licenses: .bin/ory
format-licenses: .bin/ory ## Format license headers
.bin/ory dev headers copyright --type=open-source --exclude=src/plugins

.PHONY: install
install: code-examples/protect-page-login/nextjs-12/package-lock.json code-examples/protect-page-login/nextjs/package-lock.json code-examples/protect-page-login/expressjs/package-lock.json package-lock.json code-examples/protect-page-login/go/go.sum code-examples/auth-api/expressjs/package-lock.json code-examples/protect-page-login/vue/package-lock.json code-examples/protect-page-login/flutter_web_redirect/pubspec.lock code-examples/protect-page-login/react/package-lock.json
install: code-examples/protect-page-login/nextjs-12/package-lock.json code-examples/protect-page-login/nextjs/package-lock.json code-examples/protect-page-login/expressjs/package-lock.json package-lock.json code-examples/protect-page-login/go/go.sum code-examples/auth-api/expressjs/package-lock.json code-examples/protect-page-login/vue/package-lock.json code-examples/protect-page-login/flutter_web_redirect/pubspec.lock code-examples/protect-page-login/react/package-lock.json ## Install all dependencies
cd code-examples/protect-page-login/nextjs-12 && npm i
cd code-examples/protect-page-login/nextjs && npm i
cd code-examples/protect-page-login/expressjs && npm i
Expand All @@ -25,21 +30,25 @@ install: code-examples/protect-page-login/nextjs-12/package-lock.json code-examp
cd code-examples/protect-page-login/react && npm i

.PHONY: build-examples
build-examples:
build-examples: ## Build all code examples
cd code-examples/protect-page-login/nextjs-12 && npm run build
cd code-examples/protect-page-login/nextjs && npm run build
cd code-examples/protect-page-login/flutter_web_redirect && flutter build web --web-renderer html
cd code-examples/protect-page-login/vue && VUE_APP_API_URL=http://localhost:4007 VUE_APP_ORY_URL=http://localhost:3006 npm run build
cd code-examples/protect-page-login/react && npm run build
cd code-examples/protect-page-login/dotnet && docker build --build-arg APP_DIR=01-basic -t dotnet-01-basic .

licenses: .bin/licenses node_modules # checks open-source licenses
licenses: .bin/licenses node_modules ## Check open-source licenses
.bin/licenses

.PHONY: test
test: install build-examples .bin/ory
test: install build-examples .bin/ory ## Run tests
./src/scripts/test.sh

.PHONY: dev
dev: node_modules ## Start local development server
npm run start

.bin/licenses: Makefile
curl https://raw.githubusercontent.com/ory/ci/master/licenses/install | sh

Expand Down
10 changes: 5 additions & 5 deletions code-examples/protect-page-login/react/src/index.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
font-family:
source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
2 changes: 0 additions & 2 deletions docs/console/change-owner.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ appropriate instructions below based on your project's status.
For most projects, which are already within a workspace, transferring ownership is simple.

1. **Adding a new owner**:

1. Select the workspace or project.
2. Navigate to the **"Workspace settings"**.
3. Select the **"Members"** section.
Expand All @@ -37,7 +36,6 @@ For legacy projects that were created before the introduction of workspaces, you
transfer.

1. **Moving the project to a workspace**:

1. First, select the project you want to transfer.
2. Go to the [project settings](https://console.ory.sh/projects/7c256603-6750-4f22-8fc0-9430fc3fc747/settings) and click on
_"Move project"_:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,12 @@ The code used in the following quickstart is available in the

5. Create a new folder named `app` in the root of your project. Inside the `app` folder, create a new folder named `auth`. Inside
the `auth` folder, create the following files:

- `login/page.tsx`
- `registration/page.tsx`
- `recovery/page.tsx`
- `verification/page.tsx`

Additionally, create a `settings` folder in the `app` directory:

- `settings/page.tsx`

Each of these files will contain the respective Ory Elements component for the self-service flow.
Expand Down Expand Up @@ -150,7 +148,6 @@ The code used in the following quickstart is available in the

6. Run the application and create your first user by navigating to `/auth/registration`. After registration, you can log in at
`/auth/login`. You can also access the other self-service flows at the following URLs:

- Recovery: `/auth/recovery`
- Verification: `/auth/verification`
- Settings: `/settings`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,12 @@ The code used in the following quickstart is available in the

4. Create a new folder named `pages` in the root of your project. Inside the `pages` folder, create a new folder named `auth`.
Inside the `auth` folder, create the following files:

- `login.tsx`
- `registration.tsx`
- `recovery.tsx`
- `verification.tsx`

Additionally, create a `settings` folder in the `pages` directory:

- `settings.tsx`

Each of these files will contain the respective Ory Elements component for the self-service flow.
Expand Down Expand Up @@ -120,7 +118,6 @@ The code used in the following quickstart is available in the

5. Run the application and create your first user by navigating to `/auth/registration`. After registration, you can log in at
`/auth/login`. You can also access the other self-service flows at the following URLs:

- Recovery: `/auth/recovery`
- Verification: `/auth/verification`
- Settings: `/settings`
Expand Down
1 change: 0 additions & 1 deletion docs/getting-started/integrate-auth/35_react-native.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ Follow these steps to run the app locally in an emulated iOS environment:
:::tip

You can also use these commands:

- `npm start` opens a dashboard where you can choose to run the app in iOS or Android simulated environments.
- `npm run android` runs the app in the Android environment.

Expand Down
1 change: 0 additions & 1 deletion docs/guides/pagination.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ Imagine you have 300 customers in your Ory project, and you want to list them 10
```

3. **Understanding the Link Header**:

- The `first` link always points to the first page of results. Its token (in this case, `00000000-0000-0000-0000-000000000000`)
remains constant.
- The `next` link points to the next page of results. Its token (e.g., `30f8507f-40e6-44b9-924f-5f814e3f072e`) is unique and
Expand Down
83 changes: 56 additions & 27 deletions docs/guides/rate-limits.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -162,58 +162,87 @@ Endpoint based rate limits are controls applied to individual API endpoints with
which govern overall project request volumes, endpoint based rate limits focus on safeguarding specific functionalities against
abuse.

### How endpoint based rate limits work
### Purpose of endpoint-based rate limits

These limits act as a first line of defense for your project endpoints. They analyze incoming request patterns and consider
factors such as:

- Source IP Address: Identifies and potentially blocks requests from suspicious sources or those exhibiting behavior indicative of
malicious activity.
- Request Frequency: Monitors how often requests are made to a specific endpoint to detect and thwart attempts to overwhelm the
system or exploit vulnerabilities.
- User Authentication: (If applicable) Considers whether requests are authenticated and may apply different limits for
authenticated vs. unauthenticated requests.
- Request Method: May apply different limits based on the HTTP method used (GET, POST, etc.).
- IP Whitelist Status: Applies higher limits to whitelisted IPs for Enterprise and Growth customers.

### Purpose endpoint based rate limits

Ory implements endpoint based rate limits to proactively secure individual endpoints and protect against common attack vectors
Ory implements endpoint-based rate limits to proactively secure individual endpoints and protect against common attack vectors
like brute-force and credential stuffing, while allowing for higher volumes of legitimate traffic from trusted sources. These
attacks typically involve numerous attempts to guess credentials or exploit vulnerabilities, often from a limited set of IP
addresses.

1. Enhanced security:

1. **Enhanced security:**
- Restricts the number of requests from specific sources within a given timeframe.
- Makes it significantly harder for attackers to succeed with brute-force or credential stuffing attacks.
- Strengthens the security of your Ory projects and protects sensitive user data.

2. Protection against malicious bots:

2. **Protection against malicious bots:**
- Differentiates between genuine user traffic and potentially harmful bot activity.
- Analyzes request patterns to identify and block automated malicious activities.

3. Safeguarding specific endpoints:

3. **Safeguarding specific endpoints:**
- Offers granular control over how each endpoint handles traffic and responds to potential threats.
- Allows fine-tuning of security measures for individual endpoints.
- Optimizes protection without compromising the user experience.

4. Fair usage:

4. **Fair usage:**
- Complements project rate limits in ensuring fair resource allocation.
- Contributes to a fairer and more stable platform for all users by mitigating abusive traffic.

5. Flexibility for high volume legitimate traffic:
5. **Flexibility for high-volume legitimate traffic:**
- Provides options for Enterprise and Growth customers to whitelist internal IPs for higher rate limits.
- Balances security needs with the requirements of high-volume legitimate traffic.

### Notes on rate limit rules
### Types of endpoint-based protection

These limits act as a first line of defense for your project endpoints. Ory implements multiple layers of endpoint-based
protection:

#### Traditional Rate Limiting

Analyzes incoming request patterns and considers factors such as:

- Source IP Address: Identifies and potentially blocks requests from suspicious sources or those exhibiting behavior indicative of
malicious activity.
- Request Frequency: Monitors how often requests are made to a specific endpoint to detect and thwart attempts to overwhelm the
system or exploit vulnerabilities.
- User Authentication: (If applicable) Considers whether requests are authenticated and may apply different limits for
authenticated vs. unauthenticated requests.
- Request Method: May apply different limits based on the HTTP method used (GET, POST, etc.).
- IP Whitelist Status: Applies higher limits to whitelisted IPs for Enterprise and Growth customers.

#### Inflight Request Limiting

In addition to traditional rate limiting, Ory employs inflight request limiting to protect critical administrative resources from
concurrent access issues. This mechanism prevents multiple parallel requests to sensitive endpoints that could cause data
inconsistency or resource conflicts.

The inflight rate limiting middleware protects critical Kratos endpoints that could be subject to concurrent request attacks,
preventing race conditions and ensuring data consistency. This protection ensures that administrative operations complete safely
without interference from concurrent requests, maintaining data integrity and system stability.

### Protected endpoints

The following endpoints are protected by different types of rate limiting:

| Type | Endpoint | HTTP Methods | Ratelimit Key | Action |
| ----------- | --------------------------------- | ----------------- | ------------------------------------------ | -------------------------------------- |
| Brute-force | | | | To be added later |
| Inflight | `/admin/identities` | POST, PUT, DELETE | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) |
| Inflight | `/admin/identities/{id}` | PUT, DELETE | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) |
| Inflight | `/admin/identities/{id}/sessions` | DELETE | `{project_id} + {full_path}` | Blocks concurrent requests (enforced) |
| Inflight | `/admin/sessions` | DELETE | `{project_id} + {full_path}` | Logs concurrent requests (report-only) |
| Inflight | `/admin/sessions/{id}` | DELETE, PATCH | `{project_id} + {full_path}` | Logs concurrent requests (report-only) |
| Inflight | `/admin/sessions/{id}/extend` | PATCH | `{project_id} + {full_path}` | Logs concurrent requests (report-only) |
| Inflight | `/self-service/recovery` | POST | `{project_id} + {path} + {email\|flow_id}` | Logs concurrent requests (report-only) |

**Note**: Report-only endpoints are observed over a period of time before enforcement is enabled. They currently log rate limit
violations for monitoring purposes but do not block requests, while enforced endpoints return HTTP 429 when rate limits are
exceeded. GET, OPTIONS, and HEAD requests are exempt from rate limiting.

### Configuration and management

#### Rule management

The endpoint based rate limit rules are set and managed by Ory. These rules are not directly configurable by Enterprise and Growth
The endpoint-based rate limit rules are set and managed by Ory. These rules are not directly configurable by Enterprise and Growth
customers yet.

#### IP Whitelisting for Enterprise and Growth plans
Expand Down
3 changes: 2 additions & 1 deletion docs/kratos/guides/upgrade.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ Should you run into problems with the upgrade, consider a stepped upgrade and pl
In [Ory Kratos v0.7](https://github.com/ory/kratos/blob/v0.7.0-alpha.1/CHANGELOG.md#breaking-changes) the cookie behavior has
changed. Review
[changes in the exemplary self-service user interface](https://github.com/ory/kratos-selfservice-ui-node/commit/e7fa292968111e06401fcfc9b1dd0e8e285a4d87).
Visit the [Cookie Settings](https://www.ory.sh/kratos/docs/guides/multi-domain-cookies/#cookies) document for more information.
Visit
the [Cookie Settings](https://www.ory.sh/kratos/docs/guides/multi-domain-cookies/#cookies) document for more information.
1 change: 0 additions & 1 deletion docs/kratos/mfa/20_webauthn-fido-yubikey.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ If you are using the Ory Account Experience, skip the 4. step

4. Define the origin of your login page. Set it to the exact URL of the page that prompts the user to use WebAuthn. The relevant
items are:

- scheme (`http` or `https`)
- host (`auth.example.com`)
- port (`4455`)
Expand Down
1 change: 0 additions & 1 deletion docs/kratos/passwordless/00_overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ The main steps in the passwordless login flow are, as follows:
dialog in the browser, asking the user to choose an authenticator.
4. WebAuthn delegates identity verification to the browser, passing the challenge and the choice of authenticator to the browser.
The browser invokes the chosen authenticator to verify the user's identity.

- **On-device authenticator:** If the user authenticates successfully, the platform selects the key pair that matches this app
and uses the private key to sign the challenge.
- **External authenticator:** Identity verification is delegated to the external device, which holds the private key that is
Expand Down
1 change: 0 additions & 1 deletion docs/kratos/social-signin/20_microsoft.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ OR

2. To authenticate users with Microsoft accounts that are not limited to a specific organization, choose from the following values
for the **Tenant** field:

- `organizations` to allow users with work or school accounts
- `consumers` to allow users with personal accounts
- `common` to allow both kinds of accounts
Expand Down
1 change: 0 additions & 1 deletion docs/kratos/social-signin/42_salesforce.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Follow these steps to add Salesforce as a social sign-in provider to your projec
8. Create the app.
9. Go to the **OAuth Settings** of your newly created connected app, click on **Manage Consumer Details** and copy the following
data to the corresponding fields in the form in the Ory Console:

- **Consumer Key** (called **Client ID** in Ory)
- **Consumer Secret** (called **Client Secret** in Ory)

Expand Down
3 changes: 0 additions & 3 deletions docs/oathkeeper/api-access-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,13 @@ Access Rules have four principal keys:
- set to `/api/v1`: Incoming HTTP Request at `/api/v1/users` -> Forwarding HTTP Request at `/users`.
- unset: Incoming HTTP Request at `/api/v1/users` -> Forwarding HTTP Request at `/api/v1/users`.
- `match` (object): Defines the URL(s) this Access Rule should match.

- `methods` (string[]): Array of HTTP methods (for example GET, POST, PUT, DELETE, ...).
- `url` (string): The URL that should be matched. You can use regular expressions or glob patterns in this field to match more
than one url. The matching strategy (glob or regexp) is defined in the global configuration file as
`access_rules.matching_strategy`. This matcher ignores query parameters. Regular expressions (or glob patterns) are
encapsulated in brackets `<` and `>`.

Regular expressions examples:

- `https://mydomain.com/` matches `https://mydomain.com/` and doesn't match `https://mydomain.com/foo` or
`https://mydomain.com`.
- `<https|http>://mydomain.com/<.*>` matches:`https://mydomain.com/` or `http://mydomain.com/foo`. Doesn't match:
Expand All @@ -98,7 +96,6 @@ Access Rules have four principal keys:
`http://mydomain.com/protected`

[Glob](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm) patterns examples:

- `https://mydomain.com/<m?n>` matches `https://mydomain.com/man` and does not match `http://mydomain.com/foo`.
- `https://mydomain.com/<{foo*,bar*}>` matches `https://mydomain.com/foo` or `https://mydomain.com/bar` and doesn't match
`https://mydomain.com/any`.
Expand Down
1 change: 0 additions & 1 deletion docs/oauth2-oidc/resource-owner-password-grant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ system or a highly privileged application. This grant type works as follows:

1. The resource owner (i.e., the user) provides their username and password directly to the client.
2. The client sends a POST request with the following parameters in the request body using form encoding to the token endpoint:

- `grant_type`: The value must be `password`.
- `client_id`: The ID of the client making the request.
- `client_secret`: The client secret used to authenticate the client. Only necessary if `token_endpoint_auth_method` is set to
Expand Down
1 change: 0 additions & 1 deletion docs/polis/guides/service.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ To connect PlanetScale database with Ory Polis, follow the below steps:
2. Get your database
[connection URL from the PlanetScale](https://planetscale.com/docs/tutorials/deploy-to-netlify#get-your-connection-string-from-planetscale)
3. Set the following environment variables

- `DB_ENGINE=planetscale`
- `DB_TYPE=mysql`
- `DB_SSL=true`
Expand Down
Loading
Loading