Overview
Matcher’s security architecture is built on several layers. Every API request passes through multiple security checkpoints before reaching your data.
Then authentication verifies who you are:
- Tenant isolation ensures you only see your own data.
- RBAC checks whether you’re allowed to perform the action.
Layer protection
| Layer | Protection |
|---|---|
| Transport | TLS 1.2+ encryption |
| Authentication | JWT tokens via lib-auth |
| Tenant Isolation | Schema-per-tenant PostgreSQL |
| Authorization | Role-based access control |
| Audit | Immutable append-only logs |
| Storage | Encryption at rest |
Authentication
Matcher uses the shared
lib-auth library (v2) for authentication, supporting JWT-based access control with HMAC signing.
Configuration
Three environment variables control authentication:| Variable | Required | Description |
|---|---|---|
AUTH_ENABLED | Yes | Enable or disable authentication (true/false) |
AUTH_SERVICE_ADDRESS | When auth enabled | Address of the external authorization service |
AUTH_JWT_SECRET | When auth enabled | Shared secret for HMAC token signature verification |
AUTH_ENABLED=false (development only), Matcher uses a default tenant ID (11111111-1111-1111-1111-111111111111) and skips authorization checks.
JWT token structure
Matcher validates JWTs signed with HMAC algorithms (HS256, HS384, HS512). The token must include tenant identification claims:| Claim | Required | Description |
|---|---|---|
tenant_id or tenantId | Yes | Tenant UUID for schema isolation |
tenant_slug or tenantSlug | No | Human-readable tenant identifier |
sub | No | User ID (used for audit logging) |
exp | Yes | Token expiration time |
nbf | No | Not-before time (token is invalid before this) |
Required headers
All API requests must include authentication:Token validation
Matcher validates tokens on every request:- Signature verification: Validates HMAC signature using the configured shared secret
- Expiration check: Rejects expired tokens (
expclaim) - Not-before check: Rejects tokens used before their
nbftime - Tenant extraction: Extracts
tenant_idfor schema isolation
Authorization (RBAC)
Role-based access control protects all API endpoints. Matcher delegates authorization to an external auth service via
lib-auth. Permissions are granular and follow the pattern resource:sub-resource:action.
Permission structure
configuration:context:create— Create reconciliation contextsmatching:job:run— Execute matching jobsexception:exception:resolve— Resolve exceptions
Complete permission list
Matcher defines six resource domains. Each endpoint requires a specific permission checked against the external authorization service.Configuration
| Permission | Description |
|---|---|
configuration:context:create | Create reconciliation contexts |
configuration:context:read | View contexts |
configuration:context:update | Update contexts |
configuration:context:delete | Delete contexts |
configuration:source:create | Create data sources |
configuration:source:read | View source configuration |
configuration:source:update | Modify source settings |
configuration:source:delete | Remove data sources |
configuration:field-map:create | Create field mappings |
configuration:field-map:read | View field mappings |
configuration:field-map:update | Update field mappings |
configuration:field-map:delete | Delete field mappings |
configuration:rule:create | Create match rules |
configuration:rule:read | View match rules |
configuration:rule:update | Update match rules |
configuration:rule:delete | Delete match rules |
configuration:fee-schedule:create | Create fee schedules |
configuration:fee-schedule:read | View fee schedules |
configuration:fee-schedule:update | Update fee schedules |
configuration:fee-schedule:delete | Delete fee schedules |
configuration:schedule:create | Create schedules |
configuration:schedule:read | View schedules |
configuration:schedule:update | Update schedules |
configuration:schedule:delete | Delete schedules |
Ingestion
| Permission | Description |
|---|---|
ingestion:import:create | Upload transaction files |
ingestion:job:read | View import jobs and transaction details |
ingestion:transaction:ignore | Mark transactions as ignored |
ingestion:transaction:search | Search transactions |
Matching
| Permission | Description |
|---|---|
matching:job:run | Execute match runs |
matching:job:read | View match run results and groups |
matching:job:delete | Delete match groups (unmatch) |
matching:adjustment:create | Create adjustment entries |
Exception
| Permission | Description |
|---|---|
exception:exception:read | View exceptions and history |
exception:exception:resolve | Force match or adjust entries |
exception:exception:dispatch | Dispatch exceptions to external systems |
exception:callback:process | Process external webhook callbacks |
exception:dispute:read | View disputes |
exception:dispute:write | Create disputes, close disputes, submit evidence |
exception:comment:write | Add or delete comments on exceptions |
Governance
| Permission | Description |
|---|---|
governance:audit:read | View audit logs |
governance:archive:read | View and download archives |
governance:actor-mapping:read | View actor mappings |
governance:actor-mapping:write | Create or update actor mappings |
governance:actor-mapping:delete | Delete actor mappings |
Reporting
| Permission | Description |
|---|---|
reporting:dashboard:read | Access dashboard analytics and metrics |
reporting:export:read | View and export reports (matched, unmatched, summary, variance) |
reporting:export-job:write | Create and cancel export jobs |
reporting:export-job:read | View export job status and download exports |
Role management
The external authorization service manages roles, not Matcher itself. Configure roles and their associated permissions in your identity provider or auth service. Matcher checks permissions on each request by calling the auth service with the required resource and action.Tenant isolation
Matcher uses schema-per-tenant isolation in PostgreSQL, providing strong data separation between tenants.
How it works
When a request arrives, Matcher extracts the tenant ID from the JWT token (never from query parameters or headers you control). It then sets the database connection to use that tenant’s schema viaSET LOCAL search_path, so every query runs in complete isolation.
Even if a bug existed in the application layer, the database enforces separation. Schema isolation is applied per-transaction to prevent connection pool pollution.
- Tenant ID from JWT only: Never accepted from request parameters
- Automatic schema selection: Applied via
auth.ApplyTenantSchema() - Per-transaction isolation: Uses
SET LOCAL search_pathto scope each database transaction - No cross-tenant access: Database enforces isolation
Isolation guarantees
| Guarantee | Implementation |
|---|---|
| Data isolation | Separate PostgreSQL schemas |
| Query scoping | SET LOCAL search_path per transaction |
| No tenant spoofing | Tenant from JWT only |
| Audit separation | Per-tenant audit tables |
Audit trail
Matcher records all actions in an immutable, append-only audit log for compliance and forensics.
Audited events
| Category | Events |
|---|---|
| Data Access | View matches, view exceptions, export data |
| Data Modification | Create match, resolve exception, update rules |
| Configuration | Create context, modify source, change settings |
Query audit logs
Use the governance audit log endpoints to retrieve audit records:Actor mappings and privacy
Actor mappings associate system identifiers (such as JWT
sub claims) with human-readable display names and email addresses. This improves audit log readability without storing personal data in every log entry.
Manage actor mappings
cURL
GDPR pseudonymization
To comply with right-to-erasure requests, pseudonymize an actor to replace their personal data with[REDACTED]. This action is irreversible.
cURL
Audit log archives
Historical audit logs are periodically compressed and moved to long-term storage. Use the archive endpoints to list and download archived data for compliance reviews.cURL
Data encryption
Encryption in transit
TLS encrypts all data transmitted to and from Matcher.| Requirement | Configuration |
|---|---|
| Protocol | TLS 1.2 or higher |
| Cipher suites | Strong ciphers only |
| Certificate | Valid CA-signed certificate |
| HSTS | Enabled with 1-year max-age |
Encryption at rest
| Data Type | Encryption Method |
|---|---|
| Database | PostgreSQL TDE (Transparent Data Encryption) |
| File storage | AES-256 encryption |
| Backups | Encrypted before storage |
| Secrets | Vault with envelope encryption |
SOX compliance
Matcher maintains records for SOX (Sarbanes-Oxley) audit requirements.
SOX control features
| Control | Matcher Feature |
|---|---|
| Segregation of duties | RBAC with granular permissions |
| Change management | Audit trail for all configuration changes |
| Access control | JWT authentication with role enforcement |
| Audit trail | Immutable append-only logs |
| Data integrity | Transaction checksums and validation |
API security
Rate limiting
Some endpoints include additional rate limiting to protect against abuse:| Endpoint Type | Rate Limited |
|---|---|
| Exception dispatch | Yes |
| Export endpoints | Yes |
| Callback processing | Yes |
SSRF protection
Matcher blocks outbound HTTP requests to private IP ranges when dispatching exceptions to external systems. This prevents Server-Side Request Forgery (SSRF) attacks. Blocked ranges include10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, and IPv6 equivalents.
Webhook signature verification
Matcher signs outbound webhook payloads with HMAC-SHA256 using a shared secret. The signature appears in theX-Signature-256 header, allowing receivers to verify authenticity.
Best practices
Use least privilege access
Use least privilege access
Grant users only the permissions they need. Start with minimal access and add permissions as needed.
Rotate credentials regularly
Rotate credentials regularly
Implement automatic rotation for service credentials and JWT secrets. Use short-lived tokens where possible.
Enable audit logging
Enable audit logging
Keep audit logs enabled and review them regularly. Set up alerts for suspicious activity.
Use rate limiting
Use rate limiting
Keep default rate limits enabled to protect against abuse. Adjust thresholds based on expected traffic patterns.
Review access regularly
Review access regularly
Conduct periodic access reviews. Remove access promptly when users change roles or leave.
Verify webhook signatures
Verify webhook signatures
Always validate HMAC-SHA256 signatures on webhook payloads to confirm they originate from Matcher.
Monitor security events
Monitor security events
Set up real-time monitoring and alerting for security events. Investigate anomalies promptly.

