Skip to content
Open
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
11 changes: 11 additions & 0 deletions docs/resource-specific-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,8 @@ NetworkACLs have the following key properties:
- `scope`: The scope of the rule ('management', 'authentication', or 'tenant')
- `match` or `not_match`: Criteria for matching requests

The `match` and `not_match` criteria also support an `auth0_managed` array for matching Auth0-managed IP ranges (e.g. `auth0.icloud_relay_proxy`, `auth0.low_reputation`). Each value must follow the pattern `^auth0\.[^.\s]+$`. This is an Early Access feature gated behind the `tenant_acl_curated_blocklists` feature flag and requires the `advanced-breached-password-detection` entitlement; the API rejects rules using `auth0_managed` with an HTTP 403 if the tenant is not entitled.

**YAML Example**

```yaml
Expand All @@ -893,6 +895,15 @@ networkACLs:
scope: 'management'
not_match:
user_agents: ['BadBot/1.0']
- description: 'Block iCloud Private Relay Exits'
active: true
priority: 4
rule:
action:
block: true
scope: 'tenant'
match:
auth0_managed: ['auth0.icloud_relay_proxy']
```

**Directory Example**
Expand Down
9 changes: 9 additions & 0 deletions src/tools/auth0/handlers/networkACLs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ const MatchSchema = {
uniqueItems: true,
minItems: 1,
},
auth0_managed: {
type: 'array',
items: {
type: 'string',
pattern: '^auth0\\.[^.\\s]+$',
},
uniqueItems: true,
minItems: 1,
},
geo_country_codes: {
type: 'array',
items: {
Expand Down
63 changes: 62 additions & 1 deletion test/tools/auth0/handlers/networkACLs.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { PromisePoolExecutor } from 'promise-pool-executor';
import { expect } from 'chai';
const Ajv = require('ajv');

import NetworkACLsHandler from '../../../../src/tools/auth0/handlers/networkACLs';
import NetworkACLsHandler, { schema } from '../../../../src/tools/auth0/handlers/networkACLs';
import pageClient from '../../../../src/tools/auth0/client';
import { mockPagedData } from '../../../utils';

Expand Down Expand Up @@ -90,6 +91,66 @@ describe('#networkACLs handler', () => {
});
});

describe('#networkACLs schema', () => {
const ajv = new Ajv({ useDefaults: true, nullable: true });

it('should pass schema validation for auth0_managed in match', () => {
const valid = ajv.validate(schema, [
{
description: 'Block iCloud Private Relay Exits',
active: true,
priority: 1,
rule: {
action: { block: true },
scope: 'tenant',
match: {
auth0_managed: ['auth0.icloud_relay_proxy'],
},
},
},
]);
expect(valid).to.equal(true);
expect(ajv.errors).to.be.null;
});

it('should pass schema validation for auth0_managed in not_match', () => {
const valid = ajv.validate(schema, [
{
description: 'Allow unless low-reputation',
active: true,
priority: 1,
rule: {
action: { allow: true },
scope: 'tenant',
not_match: {
auth0_managed: ['auth0.low_reputation'],
},
},
},
]);
expect(valid).to.equal(true);
expect(ajv.errors).to.be.null;
});

it('should fail schema validation for auth0_managed values not matching the pattern', () => {
const valid = ajv.validate(schema, [
{
description: 'Invalid auth0_managed value',
active: true,
priority: 1,
rule: {
action: { block: true },
scope: 'tenant',
match: {
auth0_managed: ['icloud_relay_proxy'],
},
},
},
]);
expect(valid).to.equal(false);
});
});

describe('#networkACLs process', () => {
it('should return empty if no networkACLs asset', async () => {
const auth0 = {
Expand Down