diff --git a/src/routes/blog/post/the-appwrite-network/+page.markdoc b/src/routes/blog/post/the-appwrite-network/+page.markdoc index 38ec96585eb..5da0b997abe 100644 --- a/src/routes/blog/post/the-appwrite-network/+page.markdoc +++ b/src/routes/blog/post/the-appwrite-network/+page.markdoc @@ -21,7 +21,7 @@ faqs: - question: "Can I control where my project's data is stored?" answer: "Yes. When you create a project, you can choose the region where your data lives. The data stays in that region for compliance, while edges and the CDN make it accessible to users worldwide with low latency." - question: "Does Appwrite offer a Web Application Firewall?" - answer: "Yes. The [WAF](/docs/products/network/waf) is available to enterprise customers and inspects HTTP and HTTPS traffic at OSI Layer 7. It blocks common attacks like SQL injection, XSS, and CSRF, and includes customizable rulesets managed through a dedicated success manager." + answer: "Yes. The [WAF](/docs/products/network/firewall) is available to enterprise customers and inspects HTTP and HTTPS traffic at OSI Layer 7. It blocks common attacks like SQL injection, XSS, and CSRF, and includes customizable rulesets managed through a dedicated success manager." --- We are happy to announce the launch of the Appwrite Network, a network of cloud regions and edge locations (edges) to improve Appwrite Cloud availability, performance, and compliance with local regulations. This will provide Appwrite developers and teams with the best tools and infrastructure to build, deploy, and scale your applications. This brings us closer to the Appwrite mission of making software development more accessible and enjoyable for all developers. @@ -100,7 +100,7 @@ Moreover, the CDN includes integrated DDoS protection that combines standard tra # Web application firewall (WAF) -Our [Web Application Firewall](/docs/products/network/waf) (WAF) is now available exclusively to enterprise customers, providing a crucial protective layer for your applications. Operating at OSI Layer 7, the WAF inspects and filters all HTTP/HTTPS traffic in real time, effectively blocking common web vulnerabilities such as SQL injection, XSS, and CSRF, while also mitigating application-level DDoS attacks. +Our [Web Application Firewall](/docs/products/network/firewall) (WAF) is now available exclusively to enterprise customers, providing a crucial protective layer for your applications. Operating at OSI Layer 7, the WAF inspects and filters all HTTP/HTTPS traffic in real time, effectively blocking common web vulnerabilities such as SQL injection, XSS, and CSRF, while also mitigating application-level DDoS attacks. Customizable rulesets allow you to tailor the WAF to your application's specific needs, with detailed analysis of request headers, payloads, and query strings to identify and neutralize threats before they reach your infrastructure. Setup and configuration are managed through your dedicated Appwrite success manager, ensuring that the WAF adapts to evolving security challenges and compliance requirements. To learn more about our enterprise plan, you can [contact us](/contact-us/enterprise). diff --git a/src/routes/docs/products/network/+layout.svelte b/src/routes/docs/products/network/+layout.svelte index 3e18199798b..41046b9635e 100644 --- a/src/routes/docs/products/network/+layout.svelte +++ b/src/routes/docs/products/network/+layout.svelte @@ -35,6 +35,10 @@ { label: 'Endpoints', href: '/docs/products/network/endpoints' + }, + { + label: 'Firewall', + href: '/docs/products/network/firewall' } ] }, @@ -61,10 +65,6 @@ label: 'TLS', href: '/docs/products/network/tls' }, - { - label: 'WAF', - href: '/docs/products/network/waf' - }, { label: 'Compression', href: '/docs/products/network/compression' diff --git a/src/routes/docs/products/network/+page.markdoc b/src/routes/docs/products/network/+page.markdoc index 9e4255a8d53..f4046b6ce70 100644 --- a/src/routes/docs/products/network/+page.markdoc +++ b/src/routes/docs/products/network/+page.markdoc @@ -70,8 +70,8 @@ Protects against distributed denial-of-service attacks, ensuring uninterrupted a {% cards_item href="/docs/products/network/tls" title="Transport Layer Security (TLS)" %} Encrypts data in transit for secure and private communication. {% /cards_item %} -{% cards_item href="/docs/products/network/waf" title="Web Application Firewall (WAF)" %} -Shields applications from common web vulnerabilities and attacks on the application layer. +{% cards_item href="/docs/products/network/firewall" title="Firewall" %} +Controls the traffic that reaches your project with rules that block, challenge, rate limit, or redirect requests. {% /cards_item %} {% cards_item href="/docs/products/network/compression" title="Compression" %} Reduces data size in transit to improve transfer speed and efficiency. diff --git a/src/routes/docs/products/network/firewall/+layout@docs.svelte b/src/routes/docs/products/network/firewall/+layout@docs.svelte new file mode 100644 index 00000000000..fd8a2233934 --- /dev/null +++ b/src/routes/docs/products/network/firewall/+layout@docs.svelte @@ -0,0 +1,64 @@ + + + + + + diff --git a/src/routes/docs/products/network/firewall/+page.markdoc b/src/routes/docs/products/network/firewall/+page.markdoc new file mode 100644 index 00000000000..ff6455d46ac --- /dev/null +++ b/src/routes/docs/products/network/firewall/+page.markdoc @@ -0,0 +1,44 @@ +--- +layout: article +title: Firewall +description: Control the traffic that reaches your Appwrite project with firewall rules that block, challenge, rate limit, or redirect requests at the edge. +--- + +Appwrite Firewall lets you control which requests reach your project. You define rules that match requests by attributes like IP address, country, path, or user agent, and choose what happens when they match: block the request, rate limit it, challenge it, redirect it, or explicitly allow it through. + +Rules are enforced on Appwrite's edge network, before a request reaches your [function](/docs/products/functions) or [site](/docs/products/sites). A blocked request never executes your code, never triggers a cold start, and never consumes your project's compute resources. + +# How it works {% #how-it-works %} + +Every request to your project's functions and sites passes through an Appwrite edge location. When your project has firewall rules, the edge evaluates them before running your deployment: + +1. Rules are evaluated in priority order, from the lowest priority number to the highest. +2. A rule matches when all of its conditions match the incoming request. +3. The first matching rule wins. Its action is applied and evaluation stops. +4. If no rule matches, the request continues to your function or site as usual. + +Firewall is designed to fail open. If a rule is misconfigured or cannot be evaluated, the rule is skipped and traffic continues to flow, so a broken rule degrades protection rather than availability. + +# Key concepts {% #key-concepts %} + +| Concept | Description | +| ------- | ----------- | +| [Rules](/docs/products/network/firewall/rules) | The unit of configuration. A rule combines conditions, an action, a priority, and a scope. | +| [Conditions](/docs/products/network/firewall/conditions) | What a rule matches on: IP address, country, path, HTTP method, host, or user agent. | +| [Actions](/docs/products/network/firewall/actions) | What happens on a match: deny, rate limit, challenge, redirect, or bypass. | +| [Logs](/docs/products/network/firewall/logs) | A record of the requests your rules acted on. | +| [Analytics](/docs/products/network/firewall/analytics) | Aggregated metrics on blocked, challenged, and redirected traffic. | + +# Common use cases {% #common-use-cases %} + +- Block traffic from specific IP addresses or countries. +- Rate limit expensive or sensitive endpoints, like authentication routes. +- Restrict an admin path to a known set of IP addresses. +- Challenge suspicious traffic, like requests with automation user agents. +- Redirect blocked visitors to an explanation page. + +See [Common rules](/docs/products/network/firewall/common-rules) for ready-to-use examples of each. + +# Getting started {% #getting-started %} + +Follow the [quick start](/docs/products/network/firewall/quick-start) to create your first rule from the Appwrite Console. diff --git a/src/routes/docs/products/network/firewall/actions/+page.markdoc b/src/routes/docs/products/network/firewall/actions/+page.markdoc new file mode 100644 index 00000000000..dfa6c1ca212 --- /dev/null +++ b/src/routes/docs/products/network/firewall/actions/+page.markdoc @@ -0,0 +1,62 @@ +--- +layout: article +title: Actions +description: Choose whether a firewall rule denies, rate limits, challenges, redirects, or bypasses the requests it matches. +--- + +A rule's action determines what happens to a request that matches all of the rule's conditions. Appwrite Firewall supports five actions. + +| Action | Behavior | Response | +| ------ | -------- | -------- | +| `deny` | Blocks the request. | `403` | +| `rateLimit` | Blocks the request once a request limit is exceeded. | `429` when over the limit | +| `challenge` | Requires the client to pass a verification challenge. | `403` until the challenge is passed | +| `redirect` | Redirects the request to a different URL. | `3xx` | +| `bypass` | Allows the request and stops rule evaluation. | Request continues normally | + +# Deny {% #deny %} + +Deny blocks the request outright with a `403` status code. The request never reaches your function or site. Use deny for traffic you never want to serve, like known-abusive IP addresses or countries you cannot serve. + +# Rate limit {% #rate-limit %} + +Rate limit allows matching requests up to a configured limit within a time window, tracked per client IP address. Once a client exceeds the limit, further matching requests from that client are blocked with a `429` status code until the window resets. + +| Configuration | Description | Default | +| ------------- | ----------- | ------- | +| Limit | The number of requests allowed per window. | `100` | +| Interval | The window length in seconds. | `3600` | + +Blocked responses include a `Retry-After` header indicating how many seconds the client should wait before retrying. Use rate limiting to protect expensive endpoints and to slow down brute-force attempts against authentication routes. + +# Challenge {% #challenge %} + +Challenge requires the client to prove it is a legitimate browser before the request is allowed through. Requests that have not passed the challenge receive a `403` status code. Use challenge for traffic that looks suspicious but might be human, where an outright block would be too aggressive. + +# Redirect {% #redirect %} + +Redirect sends the client to a different URL instead of serving the request. + +| Configuration | Description | Default | +| ------------- | ----------- | ------- | +| Location | The URL to redirect to. | Required | +| Status code | The redirect status code, in the `3xx` range. | `302` | + +Use redirect to send blocked visitors to an explanation page or to route traffic from specific regions to a different destination. + +# Bypass {% #bypass %} + +Bypass explicitly allows the request and stops evaluation, so no later rule can block it. Bypass is the building block for allowlists: place a bypass rule for trusted traffic at a lower priority number than a broader deny rule, and the trusted traffic is exempted from the block. See [Rules](/docs/products/network/firewall/rules#priority) for how priority ordering makes this work. + +# Response headers {% #response-headers %} + +When a firewall rule acts on a request, the response identifies the rule and action: + +| Header | Description | +| ------ | ----------- | +| `X-Appwrite-WAF-Rule` | The ID of the matched rule. | +| `X-Appwrite-WAF-Action` | The action that was applied. | +| `X-Appwrite-WAF-Challenge-Type` | The type of challenge issued. Only present on challenge responses. | +| `Retry-After` | Seconds until the rate limit window resets. Only present on rate-limited responses. | + +These headers are useful when testing new rules or debugging why a request was blocked. diff --git a/src/routes/docs/products/network/firewall/analytics/+page.markdoc b/src/routes/docs/products/network/firewall/analytics/+page.markdoc new file mode 100644 index 00000000000..2458a5d7969 --- /dev/null +++ b/src/routes/docs/products/network/firewall/analytics/+page.markdoc @@ -0,0 +1,38 @@ +--- +layout: article +title: Analytics +description: Monitor how much traffic your firewall rules block, challenge, and redirect, and see where blocked traffic comes from. +--- + +Firewall analytics aggregate what your rules are doing over time, so you can see how much traffic is filtered and where it comes from. + +Open the **Analytics** tab on the **Firewall** page in your project in the Appwrite Console to view them. + +# Metrics {% #metrics %} + +Analytics track the requests your rules acted on, grouped by outcome: + +| Metric | Description | +| ------ | ----------- | +| Blocked | Requests stopped by `deny` rules or rate limits. | +| Challenged | Requests issued a verification challenge. | +| Redirected | Requests sent to a different URL by `redirect` rules. | + +Metrics are shown as totals with trends over your selected date range, along with a time series so you can spot spikes. + +# Traffic sources {% #traffic-sources %} + +Analytics also break blocked traffic down by origin: + +- **Top blocked IP addresses** show which clients trigger your rules most, which helps identify persistent abusers worth a dedicated deny rule. +- **Top blocked countries** show the geographic distribution of filtered traffic, which helps evaluate whether geo-blocking rules are working as intended. + +# Using analytics {% #using-analytics %} + +A few patterns worth watching: + +- A sudden spike in blocked requests usually means an attack or scraper found your application, and your rules are absorbing it. +- A high challenge count with few subsequent successful requests suggests the challenged traffic was automated. +- If a rule shows no activity over a long period, verify it still matches what you intended, or consider removing it to keep your rule set easy to reason about. + +For request-level detail behind any of these numbers, switch to the [logs](/docs/products/network/firewall/logs). diff --git a/src/routes/docs/products/network/firewall/common-rules/+page.markdoc b/src/routes/docs/products/network/firewall/common-rules/+page.markdoc new file mode 100644 index 00000000000..4c4807daa73 --- /dev/null +++ b/src/routes/docs/products/network/firewall/common-rules/+page.markdoc @@ -0,0 +1,105 @@ +--- +layout: article +title: Common rules +description: Ready-to-use firewall rule patterns for geo-blocking, IP allowlists, rate limiting, and bot challenges. +--- + +These patterns cover the most common ways to use Appwrite Firewall. Each example shows the rule's action, priority, and conditions. Create them from the **Firewall** page in your project in the Appwrite Console, adjusting values to your needs. + +# Block traffic from specific countries {% #geo-blocking %} + +A single `deny` rule with a multi-value `equal` condition on `country` blocks every listed country: + +- **Action**: `deny` +- **Priority**: `10` +- **Conditions**: + +```json +[ + { "method": "equal", "attribute": "country", "values": ["KP", "IR"] } +] +``` + +To do the opposite and serve only specific countries, use `notEqual` conditions, or pair a `bypass` rule for the allowed countries with a broader `deny` rule. + +# Restrict a path to known IP addresses {% #ip-allowlist %} + +Allowlists use two rules. A `bypass` rule at a lower priority number exempts trusted traffic, and a `deny` rule behind it blocks everyone else. See [priority and evaluation order](/docs/products/network/firewall/rules#priority) for why the ordering matters. + +Rule 1 allows your trusted IP addresses through: + +- **Action**: `bypass` +- **Priority**: `5` +- **Conditions**: + +```json +[ + { "method": "startsWith", "attribute": "path", "values": ["/admin"] }, + { "method": "equal", "attribute": "ip", "values": ["203.0.113.7", "203.0.113.8"] } +] +``` + +Rule 2 blocks all other traffic to the same path: + +- **Action**: `deny` +- **Priority**: `10` +- **Conditions**: + +```json +[ + { "method": "startsWith", "attribute": "path", "values": ["/admin"] } +] +``` + +# Rate limit an authentication endpoint {% #rate-limit-auth %} + +Slow down brute-force attempts by limiting how often a single IP address can call a login route: + +- **Action**: `rateLimit` +- **Priority**: `20` +- **Configuration**: limit `10`, interval `60` seconds +- **Conditions**: + +```json +[ + { "method": "equal", "attribute": "method", "values": ["POST"] }, + { "method": "equal", "attribute": "path", "values": ["/v1/login"] } +] +``` + +Legitimate users are unaffected until they exceed 10 requests per minute, and clients over the limit receive a `429` response with a `Retry-After` header. + +# Challenge automated clients {% #challenge-bots %} + +Require verification from clients that identify as automation tools or send no user agent at all: + +- **Action**: `challenge` +- **Priority**: `30` +- **Conditions**: + +```json +[ + { + "method": "or", + "values": [ + { "method": "contains", "attribute": "userAgent", "values": ["curl", "python-requests", "Go-http-client"] }, + { "method": "isNull", "attribute": "userAgent" } + ] + } +] +``` + +# Redirect blocked visitors to an explanation page {% #redirect-blocked %} + +Instead of serving a bare `403`, send blocked traffic somewhere informative: + +- **Action**: `redirect` +- **Priority**: `10` +- **Configuration**: location `https://example.com/not-available`, status code `302` +- **Conditions**: + +```json +[ + { "method": "equal", "attribute": "country", "values": ["KP"] } +] +``` diff --git a/src/routes/docs/products/network/firewall/conditions/+page.markdoc b/src/routes/docs/products/network/firewall/conditions/+page.markdoc new file mode 100644 index 00000000000..2f0fb9fba1d --- /dev/null +++ b/src/routes/docs/products/network/firewall/conditions/+page.markdoc @@ -0,0 +1,86 @@ +--- +layout: article +title: Conditions +description: Match requests by IP address, country, path, method, host, or user agent using firewall rule conditions and operators. +--- + +Conditions define what traffic a firewall rule matches. Each condition compares one request attribute against one or more values using an operator. A rule matches a request only when all of its conditions match. + +# Structure {% #structure %} + +A condition has three parts: an attribute to inspect, an operator, and the values to compare against. + +```json +{ + "method": "equal", + "attribute": "country", + "values": ["NL", "DE"] +} +``` + +This condition matches requests originating from the Netherlands or Germany. When an operator receives multiple values, the condition matches if any one of the values matches. + +# Attributes {% #attributes %} + +| Attribute | Description | Example value | +| --------- | ----------- | ------------- | +| `ip` | The client's IP address. | `203.0.113.7` | +| `country` | The client's country as a two-letter ISO 3166-1 code, resolved from the client's IP address. | `NL` | +| `method` | The HTTP method, in uppercase. | `POST` | +| `path` | The request path. | `/v1/login` | +| `host` | The hostname the request was sent to. | `myapp.appwrite.network` | +| `userAgent` | The request's `User-Agent` header. | `Mozilla/5.0 ...` | + +# Operators {% #operators %} + +| Operator | Description | +| -------- | ----------- | +| `equal` | The attribute equals any of the values. | +| `notEqual` | The attribute does not equal any of the values. | +| `contains` | The attribute contains any of the values as a substring. | +| `notContains` | The attribute does not contain any of the values. | +| `startsWith` | The attribute starts with the value. | +| `notStartsWith` | The attribute does not start with the value. | +| `endsWith` | The attribute ends with the value. | +| `notEndsWith` | The attribute does not end with the value. | +| `lessThan` | The attribute is less than the value. | +| `lessThanEqual` | The attribute is less than or equal to the value. | +| `greaterThan` | The attribute is greater than the value. | +| `greaterThanEqual` | The attribute is greater than or equal to the value. | +| `between` | The attribute is between the two values, inclusive. | +| `notBetween` | The attribute is not between the two values. | +| `isNull` | The attribute is absent. | +| `isNotNull` | The attribute is present. | + +The `equal`, `notEqual`, `contains`, and `notContains` operators accept multiple values and match if any single value matches. The `startsWith`, `endsWith`, and relational operators compare against a single value, and `between` uses exactly two values for the range bounds. + +{% info title="Matching IP ranges" %} +The `equal` operator compares IP addresses as exact strings. To match a range of addresses, use `startsWith` with the shared prefix, for example `startsWith` on `ip` with the value `203.0.113.`. +{% /info %} + +# Combining conditions {% #combining-conditions %} + +All conditions on a rule must match, which behaves like a logical AND: + +```json +[ + { "method": "equal", "attribute": "method", "values": ["POST"] }, + { "method": "startsWith", "attribute": "path", "values": ["/v1/login"] } +] +``` + +This rule only matches `POST` requests to paths starting with `/v1/login`. + +To express alternatives beyond a multi-value `equal`, nest conditions with the logical `or` and `and` operators. A logical condition's `values` array contains other conditions: + +```json +{ + "method": "or", + "values": [ + { "method": "contains", "attribute": "userAgent", "values": ["curl", "python-requests"] }, + { "method": "isNull", "attribute": "userAgent" } + ] +} +``` + +This condition matches requests with an automation user agent or no user agent at all. Logical conditions can be nested to build more complex expressions. diff --git a/src/routes/docs/products/network/firewall/logs/+page.markdoc b/src/routes/docs/products/network/firewall/logs/+page.markdoc new file mode 100644 index 00000000000..fa4bac1c5d7 --- /dev/null +++ b/src/routes/docs/products/network/firewall/logs/+page.markdoc @@ -0,0 +1,38 @@ +--- +layout: article +title: Logs +description: Inspect the requests your firewall rules acted on, filter by rule or action, and export logs for further analysis. +--- + +Firewall logs record the requests your rules acted on, so you can verify that rules behave as intended and investigate suspicious traffic. + +Open the **Logs** tab on the **Firewall** page in your project in the Appwrite Console to browse them. + +# Log entries {% #log-entries %} + +Each log entry describes one request a rule acted on: + +| Field | Description | +| ----- | ----------- | +| Timestamp | When the request was processed. | +| Action | The action that was applied to the request. | +| IP address | The client's IP address. | +| Country | The client's country, resolved from the IP address. | +| Method and path | The HTTP method and request path. | +| Status code | The HTTP status code returned to the client. | +| Rule | The rule that matched the request. | +| User agent | The request's `User-Agent` header. | + +# Filtering {% #filtering %} + +Narrow the log view to find what you need: + +- Filter by action to see only blocked, challenged, or allowed requests. +- Filter by rule to review everything a single rule has matched. +- Search by IP address, path, rule name, or user agent. + +Filtering by rule is the fastest way to validate a rule you just created: create the rule, send a test request that should match it, and confirm the request appears in the log with the expected action. + +# Exporting {% #exporting %} + +Export the current log view as a CSV file to analyze traffic in external tools, share findings with your team, or keep records beyond the retention window. diff --git a/src/routes/docs/products/network/firewall/quick-start/+page.markdoc b/src/routes/docs/products/network/firewall/quick-start/+page.markdoc new file mode 100644 index 00000000000..ae9cf02a4ec --- /dev/null +++ b/src/routes/docs/products/network/firewall/quick-start/+page.markdoc @@ -0,0 +1,45 @@ +--- +layout: article +title: Start with Firewall +description: Create your first firewall rule in the Appwrite Console and verify that it blocks traffic. +--- + +You can create your first firewall rule in a few minutes. This example blocks all traffic to a site from a single IP address, which is an easy rule to verify with your own connection. + +{% section #create-rule step=1 title="Create a rule" %} + +In the Appwrite Console, open your project and navigate to **Firewall** in the sidebar, then open the **Rules** tab and click **Create rule**. + +Configure the rule: + +1. Give the rule a name, for example `Block test IP`. +2. Select the resource the rule applies to. Choose one of your sites or functions. +3. Set the action to **Deny**. +4. Add a condition that matches your own IP address: set the attribute to **IP address**, the operator to **equal**, and the value to your current public IP. +5. Leave the priority at its default and keep the rule enabled. + +Save the rule. Changes propagate to Appwrite's edge network automatically. +{% /section %} + +{% section #verify step=2 title="Verify the rule" %} + +Visit your site's domain from the same connection. The request is blocked with a `403` response before it reaches your deployment. + +You can confirm the firewall handled the request by inspecting the response headers: + +```http +X-Appwrite-WAF-Rule: +X-Appwrite-WAF-Action: deny +``` +{% /section %} + +{% section #clean-up step=3 title="Disable the rule" %} + +Back in the **Rules** tab, disable or delete the rule to restore your access. Disabled rules keep their configuration but are skipped during evaluation, which is useful when you want to switch protection on and off without recreating rules. +{% /section %} + +# Next steps {% #next-steps %} + +- Learn how [rules](/docs/products/network/firewall/rules) are scoped, ordered, and evaluated. +- Explore the full set of [conditions](/docs/products/network/firewall/conditions) and [actions](/docs/products/network/firewall/actions). +- Copy patterns from [common rules](/docs/products/network/firewall/common-rules) like geo-blocking and IP allowlists. diff --git a/src/routes/docs/products/network/firewall/rules/+page.markdoc b/src/routes/docs/products/network/firewall/rules/+page.markdoc new file mode 100644 index 00000000000..9b75591cb86 --- /dev/null +++ b/src/routes/docs/products/network/firewall/rules/+page.markdoc @@ -0,0 +1,56 @@ +--- +layout: article +title: Rules +description: Learn how firewall rules are structured, scoped to resources, ordered by priority, and evaluated against incoming requests. +--- + +A firewall rule tells Appwrite what traffic to match and what to do with it. Each rule combines a set of [conditions](/docs/products/network/firewall/conditions), an [action](/docs/products/network/firewall/actions), a priority, and a scope. + +# Anatomy of a rule {% #anatomy %} + +| Field | Description | +| ----- | ----------- | +| `name` | A human-friendly name for the rule. | +| `description` | An optional description of what the rule is for. | +| `resourceType` | What the rule applies to: your project's APIs, functions, or sites. | +| `resourceId` | The specific function or site the rule applies to. | +| `action` | What happens when the rule matches: `deny`, `rateLimit`, `challenge`, `redirect`, or `bypass`. | +| `priority` | The evaluation order. Rules with lower numbers are evaluated first. | +| `enabled` | Whether the rule participates in evaluation. Disabled rules are skipped. | +| `conditions` | The list of conditions a request must match for the rule to apply. | + +# Scope {% #scope %} + +Rules are scoped to a resource type, and for functions and sites, to a specific resource. A rule scoped to one site only evaluates against requests for that site's domains, and a rule scoped to one function only evaluates against that function's executions over its domain. + +# Priority and evaluation order {% #priority %} + +When a request arrives, your project's rules are sorted by priority, from the lowest number to the highest, and evaluated in that order. The first rule whose conditions all match determines the outcome, and no further rules are evaluated. + +This first-match behavior is what makes rule ordering powerful. A common pattern is to place a narrow `bypass` rule at a low priority number ahead of a broader `deny` rule, which creates an allowlist: + +1. Priority `5`: bypass requests to `/admin` from your office IP. +2. Priority `10`: deny all other requests to `/admin`. + +A request from the office IP matches the first rule and is let through. Any other request to `/admin` falls through to the second rule and is blocked. + +{% info title="Priority values" %} +Priority is a number between `-100000` and `100000`, and defaults to `0`. Leave gaps between your priority values, like `10`, `20`, `30`, so you can insert rules between existing ones later. +{% /info %} + +# Matching {% #matching %} + +A rule matches a request only when every one of its conditions matches. A rule with no conditions never matches. To express alternatives, like matching one country or another, use a single condition with multiple values, or nest conditions with the `or` operator. See [Conditions](/docs/products/network/firewall/conditions) for details. + +# Managing rules {% #managing-rules %} + +Manage rules from the **Firewall** page in your project in the Appwrite Console: + +- **Create** a rule from the **Rules** tab. You choose the action first, then add conditions and configuration specific to that action. +- **Edit** a rule to change its conditions, priority, or configuration. Changes propagate to the edge network automatically. +- **Disable** a rule to take it out of evaluation without losing its configuration. +- **Delete** a rule to remove it permanently. + +# Failure behavior {% #failure-behavior %} + +Firewall fails open. If a rule's conditions or configuration cannot be parsed, the rule is skipped and evaluation continues with the next rule. Appwrite prioritizes keeping your application reachable over enforcing a broken rule, so always verify new rules behave as expected using the [logs](/docs/products/network/firewall/logs). diff --git a/src/routes/docs/products/network/waf/+page.markdoc b/src/routes/docs/products/network/waf/+page.markdoc deleted file mode 100644 index 36c13c0dd7b..00000000000 --- a/src/routes/docs/products/network/waf/+page.markdoc +++ /dev/null @@ -1,114 +0,0 @@ ---- -layout: article -title: Web application firewall (WAF) -description: Appwrite's Web Application Firewall (WAF) provides enterprise-grade protection against web vulnerabilities like SQL injection, XSS, and DDoS attacks. ---- - -The Web Application Firewall (WAF) is a critical feature of the Appwrite Network, designed to protect applications from common web vulnerabilities and attacks. Available exclusively to enterprise customers, WAF can be configured through your Appwrite success manager to meet the specific security needs of your application. - -{% info title="Availability" %} -The WAF feature is available exclusively to enterprise customers as part of the Appwrite enterprise offering. Setup and configuration are managed through your dedicated Appwrite success manager, who ensures that the WAF aligns with your application's requirements and evolves with emerging security threats. -{% /info %} - -The WAF functions as a protective barrier at the application layer (Layer 7) of the OSI model, where it inspects and filters HTTP/HTTPS traffic in real-time. It is specifically designed to safeguard your application by analyzing request headers, payloads, and query strings to identify malicious patterns or anomalies. The WAF intercepts traffic before it reaches your application, blocking threats such as: - -- SQL injection: Malicious input targeting database queries is identified and neutralized by inspecting payloads and request parameters. -- Cross-site scripting (XSS): WAF detects and blocks scripts attempting to manipulate or steal client-side data through injection into the DOM or other contexts. -- Cross-site request forgery (CSRF): By analyzing session headers and request origins, the WAF ensures only legitimate actions are processed. -- DDoS attacks: Although primarily focused on Layer 7 attacks, the WAF works in tandem with other mitigation systems to handle floods of application-level requests. - -# Design {% #design %} - -1. **Traffic inspection** - The WAF analyzes all incoming HTTP/HTTPS requests in real-time, matching them against a dynamic set of security rules. - -2. **Threat mitigation** - Suspicious requests are blocked before they reach your application, ensuring uninterrupted service and secure user interactions. - -3. **Custom rules** - Enterprise customers can work with their success manager to define custom rules tailored to their specific application requirements. - -# Key features {% #key-features %} - -- Real-time protection: Continuous monitoring and blocking of malicious traffic. -- Customizable rulesets: Configure WAF policies to align with your application's unique architecture. -- Compliance support: Meet security standards and regulatory requirements by safeguarding sensitive data. -- Seamless integration: Fully integrated into the Appwrite network, ensuring optimal performance and low-latency security enforcement. - -# Getting started {% #getting-started %} - -If you're an enterprise customer, reach out to your success manager to enable WAF for your applications. They'll guide you through the setup process, help configure custom rules, and ensure your application is fully protected. - -For more information on upgrading to the enterprise plan, [contact sales](https://appwrite.io/contact-us/enterprise). - -## Configuration {% #configuration %} - -Appwrite's WAF is designed to adapt to the specific needs of your applications. Tailored rules and actions can be implemented to address evolving security threats and traffic patterns effectively. - -### Rules {% #rules %} - -The WAF supports the creation of fine-grained rules using logical expressions. These rules define how incoming traffic is inspected and handled. - -1. **Expression-based rules** - Use logical expressions to create granular filters for incoming requests. These expressions operate on HTTP request fields, headers, cookies, and metadata. - - Examples of configurable expressions: - - **URL matching**: Block or allow traffic based on URL patterns (e.g., `/v1/functions/*`). - - **Request method**: Filter traffic based on HTTP methods (e.g., `GET`, `POST`, `PUT`). - - **Header inspection**: Inspect headers like `User-Agent`, `Authorization`, or `X-Forwarded-For`. - - **Cookie validation**: Check for specific cookies or validate their values to identify bot or malicious traffic. - - **Rate limiting**: Match requests based on IP or session-level rate thresholds. - - **Geolocation rules**: Allow or block traffic based on the geographic location of the user. - -2. **Regular expressions (Regex)** - Use regex patterns for more advanced filtering, such as matching complex URL structures, payloads, or specific query parameters. - -3. **IP Filtering** - Define rules to block, allow, or challenge traffic from specific IP ranges or CIDR blocks. - -### Actions {% #actions %} - -Based on the defined rules, the WAF can perform various actions to handle traffic appropriately. - -1. **Allow** - Allows the request to pass through to the backend without modification. - -2. **Block** - Rejects the request entirely, responding with an appropriate HTTP status code (e.g., `403 Forbidden`). - -3. **Challenge** - Issues a challenge (e.g., CAPTCHA) to validate whether the request originates from a legitimate user. - -4. **Redirect** - Redirects the request to a specified URL. Useful for handling deprecated endpoints or re-routing unauthorized traffic. - -5. **Log** - Records the request in detailed logs for further analysis without altering the request flow. - -6. **Rate limiting** - Throttles traffic from specific IPs or sessions that exceed defined thresholds, reducing the risk of abuse or overload. - -7. **Modify request** - Dynamically alters request components, such as headers, query parameters, or cookies. - -### Examples {% #examples %} - -#### Blocking malicious bots -- **Expression**: Match requests with suspicious `User-Agent` strings or invalid headers. -- **Action**: Block or issue a CAPTCHA challenge to confirm legitimate traffic. - -#### Preventing SQL injection -- **Expression**: Match payloads or query strings containing SQL keywords like `SELECT`, `DROP`, or `--`. -- **Action**: Block the request and log it for analysis. - -#### Rate limiting by endpoint -- **Expression**: Limit requests to sensitive endpoints (e.g., `/login`) to prevent abuse. -- **Action**: Throttle or temporarily block repeated requests from the same IP. - -#### Geo-based blocking -- **Expression**: Match requests originating from specific regions or countries. -- **Action**: Block or redirect users to a region-specific notice page. - -#### Header enforcement -- **Expression**: Check for required headers (e.g., `Authorization`) on API requests. -- **Action**: Block requests missing critical headers. \ No newline at end of file