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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ node_modules

# Exclude generated OpenAPI files from the docs directory
!./openapi.json

# Ignore AGENTS.md
AGENTS.md
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[workspace]
members = [".", "macros"]

[package]
name = "openzeppelin-relayer"
version = "1.1.0"
Expand All @@ -16,6 +19,7 @@ overflow-checks = true
panic = "unwind"

[dependencies]
relayer-macros = { path = "macros" }
aws-config = { version = "1.6.3", features = ["behavior-version-latest"] }
aws-sdk-kms = "1.75.0"
actix-web = "4"
Expand Down
138 changes: 138 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,144 @@ cargo run --example generate_uuid

Copy the generated UUID and update the `API_KEY` entry in the `.env` file.

### API Key Permissions System

The relayer uses a fine-grained permission system to control access to API resources. Each API key can have multiple permission grants that specify what actions can be performed and on what scope.

#### Permission Structure

Permissions consist of two parts:
- **Action**: The operation being permitted (e.g., `relayers:read`, `transactions:execute`)
- **Scope**: Either `global` (all resources) or a list of specific resource IDs

#### Permission Format

```json
{
"action": "relayers:read",
"scope": "global"
}
```

Or with specific resource IDs:

```json
{
"action": "relayers:update",
"scope": ["sepolia-example", "mainnet-example"]
}
```

#### Action Format

Actions follow the pattern `{resource}:{operation}`:
- `relayers:read` - Read relayer information
- `relayers:create` - Create new relayers
- `relayers:update` - Update relayer configuration
- `relayers:delete` - Delete relayers
- `transactions:execute` - Execute transactions
- `signers:read`, `signers:create`, `signers:update`, `signers:delete` - Signer operations
- `notifications:read`, `notifications:create`, `notifications:update`, `notifications:delete` - Notification operations
- `api_keys:read`, `api_keys:create`, `api_keys:delete` - API key management

#### Wildcard Support

The permission system supports wildcards for flexible access control:
- `*:*` with global scope - Full system access (super admin)
- `relayers:*` with global scope - All operations on all relayers
- `relayers:*` with specific IDs - All operations on specific relayers

#### Permission Hierarchy

1. **Super Admin**: `*:*` with global scope grants unrestricted access
2. **Resource-level Admin**: `relayers:*` with global scope grants all operations on relayers
3. **Global Action**: `relayers:read` with global scope allows reading all relayers
4. **Scoped Action**: `relayers:read` with specific IDs allows reading only those relayers

#### Example Permissions

**Full access:**
```json
{
"permissions": [
{
"action": "*:*",
"scope": "global"
}
]
}
```

**Read-only access to all relayers:**
```json
{
"permissions": [
{
"action": "relayers:read",
"scope": "global"
}
]
}
```

**Update specific relayers only:**
```json
{
"permissions": [
{
"action": "relayers:update",
"scope": ["sepolia-example", "mainnet-example"]
}
]
}
```

**Multiple permissions:**
```json
{
"permissions": [
{
"action": "relayers:read",
"scope": "global"
},
{
"action": "transactions:execute",
"scope": ["sepolia-example"]
},
{
"action": "signers:*",
"scope": "global"
}
]
}
```

#### Creating API Keys with Permissions

API keys can be created via the REST API with specific permissions:

```bash
curl -X POST http://localhost:8080/api/v1/api_keys \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"name": "My API Key",
"permissions": [
{
"action": "relayers:read",
"scope": "global"
}
]
}'
```

#### Security Warning: Plugin Permissions

> **WARNING**: When granting plugin permissions, be aware that plugins have internal access to all relayers and relayer operations within the relayer service.
>
> If a plugin implements functionality that interacts with relayers (e.g., sending transactions, reading balances), granting plugin permissions effectively provides **indirect access to those relayer operations**.
>

### Starting Redis manually (without docker compose)

You can start Redis in one of two ways:
Expand Down
13 changes: 13 additions & 0 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "relayer-macros"
version = "0.1.0"
edition = "2021"
rust-version = "1.86"

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0.101"
quote = "1.0.40"
syn = { version = "2.0.106", features = ["full"] }
Loading
Loading