feat: add scoped read-only public API
This commit is contained in:
@@ -87,6 +87,7 @@ Follow-up:
|
||||
- DNS health and Cloudflare read-only inspection are in place, including zone import, record recommendations, and DNS change tracking.
|
||||
- Guided setup and operator health screens.
|
||||
- Forensic/RUF report support.
|
||||
- Email security posture beyond DMARC, including MTA-STS, TLS-RPT, BIMI, and evidence-first posture playbooks.
|
||||
|
||||
See [milestones.md](../milestones.md) for the full milestone breakdown and exit criteria.
|
||||
|
||||
@@ -120,9 +121,9 @@ The milestone breakdown in `docs/milestones.md` is intentionally focused on exit
|
||||
|
||||
### Priority (Now / Next / Later)
|
||||
|
||||
- **Now**: finish Milestones 8–9 (DNS health guidance + setup/ops polish).
|
||||
- **Next**: Milestones 10–12 (failure reports, DMARC format compatibility, Microsoft 365 ingestion).
|
||||
- **Later**: Milestones 13–16 (posture suite beyond DMARC, public API/webhooks, MSP/workspaces, AI/MCP).
|
||||
- **Now**: finish Milestone 14 (public API, webhooks, and integration templates).
|
||||
- **Next**: Milestone 15 (workspaces/MSP governance).
|
||||
- **Later**: Milestone 16 (optional AI/MCP automation).
|
||||
|
||||
### Tentative Release Plan (Subject to Change)
|
||||
|
||||
|
||||
+3
-3
@@ -214,7 +214,7 @@ Exit criteria:
|
||||
|
||||
## Milestone 13: Email Security Posture (Beyond DMARC)
|
||||
|
||||
Status: In Progress
|
||||
Status: Complete
|
||||
|
||||
Goal: turn DMARQ into a broader email authentication posture console (still privacy-first and self-hostable).
|
||||
|
||||
@@ -230,12 +230,12 @@ Exit criteria:
|
||||
|
||||
## Milestone 14: Public API, Webhooks, and Core Integrations
|
||||
|
||||
Status: Backlog
|
||||
Status: In progress
|
||||
|
||||
Goal: let DMARQ integrate cleanly into existing security and operations workflows.
|
||||
|
||||
Planned:
|
||||
- A stable, documented read-only API surface for posture and reporting queries.
|
||||
- A stable, documented read-only API surface for posture and reporting queries. Delivered with scoped `reports:read`, `posture:read`, and `tls-reports:read` API tokens, public read-only endpoints, and per-token usage audit fields.
|
||||
- Webhook event delivery for key events (new sender source, compliance drop, missing reports, alert lifecycle).
|
||||
- Integration templates for SIEM and ticketing workflows (export formats, payload schemas, examples).
|
||||
- Token/scoping model for API access that matches governance needs (service accounts, least privilege).
|
||||
|
||||
+64
-7
@@ -4,18 +4,31 @@ DMARQ provides a comprehensive REST API that allows you to integrate with extern
|
||||
|
||||
## Authentication
|
||||
|
||||
All API requests require authentication using an API key.
|
||||
Stable automation endpoints live under `/api/v1/public` and require a scoped
|
||||
API token in the `X-API-Key` header. Admin endpoints continue to require an
|
||||
administrator session or admin API key.
|
||||
|
||||
### API Keys
|
||||
|
||||
To use the API, you need to generate an API key:
|
||||
|
||||
1. Navigate to **Settings** > **API Access** in the DMARQ UI
|
||||
2. Click **Create API Key**
|
||||
3. Enter a description for the key (e.g., "Integration with Slack")
|
||||
4. Select the permissions you want to grant to this key
|
||||
5. Click **Generate Key**
|
||||
6. Copy the key immediately (it will only be shown once)
|
||||
Create scoped API tokens with:
|
||||
|
||||
```
|
||||
POST /api-tokens
|
||||
```
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "SIEM export",
|
||||
"scopes": ["reports:read", "posture:read", "tls-reports:read"]
|
||||
}
|
||||
```
|
||||
|
||||
The raw token is returned once. DMARQ stores only a hash, prefix, scopes, and
|
||||
usage audit metadata.
|
||||
|
||||
### Authentication Header
|
||||
|
||||
@@ -37,6 +50,50 @@ Replace `your-dmarq-instance.com` with your actual DMARQ hostname.
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Stable Public API
|
||||
|
||||
These endpoints are read-only and intended for automation. They are versioned
|
||||
through the `/public` path and avoid UI-specific payloads.
|
||||
|
||||
| Endpoint | Required scope | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `GET /public/domains` | `reports:read` | Domain report and DNS summary list |
|
||||
| `GET /public/domains/{domain_id}/reports` | `reports:read` | Recent DMARC aggregate report summaries |
|
||||
| `GET /public/domains/{domain_id}/posture` | `posture:read` | Evidence-first posture dashboard payload |
|
||||
| `GET /public/tls-reports/summary` | `tls-reports:read` | SMTP TLS report trends and failure groups |
|
||||
|
||||
Successful public API calls update the token's last-used timestamp, source IP,
|
||||
and usage count for auditing.
|
||||
|
||||
### API Tokens
|
||||
|
||||
#### List API Tokens
|
||||
|
||||
```
|
||||
GET /api-tokens
|
||||
```
|
||||
|
||||
Returns token metadata, scopes, activity state, and audit fields. Raw token
|
||||
secrets and hashes are never returned.
|
||||
|
||||
#### Create API Token
|
||||
|
||||
```
|
||||
POST /api-tokens
|
||||
```
|
||||
|
||||
Creates a scoped read-only token. The response includes `token` once and
|
||||
`metadata` for future list/revoke operations.
|
||||
|
||||
#### Revoke API Token
|
||||
|
||||
```
|
||||
DELETE /api-tokens/{token_id}
|
||||
```
|
||||
|
||||
Deactivates a token immediately. Revoked tokens can no longer access public API
|
||||
endpoints.
|
||||
|
||||
### Domains
|
||||
|
||||
#### List Domains
|
||||
|
||||
@@ -114,20 +114,26 @@ The `users` table stores user account information.
|
||||
| created_at | TIMESTAMP | When the account was created |
|
||||
| last_login | TIMESTAMP | When the user last logged in |
|
||||
|
||||
### API_Keys
|
||||
### API_Tokens
|
||||
|
||||
The `api_keys` table stores API keys for programmatic access.
|
||||
The `api_tokens` table stores hashed, scoped API tokens for stable read-only
|
||||
automation access. Raw token secrets are returned only once at creation time
|
||||
and are never stored.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| id | INTEGER | Primary key |
|
||||
| key_hash | VARCHAR(255) | Hashed API key |
|
||||
| user_id | INTEGER | Foreign key to users.id |
|
||||
| name | VARCHAR(100) | Name/description of the key |
|
||||
| name | VARCHAR(120) | Name/description of the token |
|
||||
| key_hash | VARCHAR(64) | SHA-256 hash of the token secret |
|
||||
| key_prefix | VARCHAR(16) | Non-secret prefix for operator identification |
|
||||
| scopes | TEXT | Comma-separated scopes such as `reports:read` |
|
||||
| active | BOOLEAN | Whether the token can be used |
|
||||
| created_at | TIMESTAMP | When the key was created |
|
||||
| expires_at | TIMESTAMP | When the key expires (optional) |
|
||||
| last_used | TIMESTAMP | When the key was last used |
|
||||
| permissions | TEXT | JSON array of permissions |
|
||||
| updated_at | TIMESTAMP | When the token row was last changed |
|
||||
| revoked_at | TIMESTAMP | When the token was revoked |
|
||||
| last_used_at | TIMESTAMP | Last successful API use |
|
||||
| last_used_ip | VARCHAR(64) | Source IP from the last successful API use |
|
||||
| usage_count | INTEGER | Successful API use count |
|
||||
|
||||
## DNS and Configuration Tables
|
||||
|
||||
@@ -234,7 +240,9 @@ The schema includes several indexes to optimize query performance:
|
||||
- `idx_users_username`: On users.username
|
||||
- `idx_users_email`: On users.email
|
||||
- `idx_domains_name`: On domains.name
|
||||
- `idx_api_keys_key_hash`: On api_keys.key_hash
|
||||
- `ix_api_tokens_key_hash`: On api_tokens.key_hash
|
||||
- `ix_api_tokens_key_prefix`: On api_tokens.key_prefix
|
||||
- `ix_api_tokens_active_scope`: On api_tokens.active and api_tokens.scopes
|
||||
- `idx_activity_logs_timestamp`: On activity_logs.timestamp
|
||||
- `idx_activity_logs_user_id`: On activity_logs.user_id
|
||||
- `idx_system_logs_timestamp`: On system_logs.timestamp
|
||||
|
||||
Reference in New Issue
Block a user