| name | opal-connector-development |
| description | Build production-ready Opal IGA custom connectors with proper authentication, API compliance, security, and testing. Use when generating, auditing, or refactoring Opal connectors. |
Opal Connector Development Skill
What This Skill Does
Enables building custom connectors for Opal Security's Identity Governance and Administration (IGA) platform. Connectors implement a standard REST API that Opal calls to manage user access across applications.
When to Use This Skill
- Generating new Opal connectors for any application
- Auditing existing connectors for compliance
- Refactoring connectors to meet gold standards
- Adding features (groups, provisioning, events)
Core Concepts
Resources: Entities users can access (databases, dashboards, repositories). Each has an ID, name, optional access levels, and optional parent-child relationships.
Access Levels: Roles/permissions for a resource (Admin, Viewer, Editor). Some resources don't need them.
Groups (optional): Collections of users that can be granted access to multiple resources. Can be nested.
Users: Individuals who need access. Identified by user_id and email.
Events (optional): Usage tracking (login.success) for Least Privilege Permission Model (LPPM) analytics.
CRITICAL: HMAC-SHA256 Authentication
Every request from Opal includes X-Opal-Signature and X-Opal-Request-Timestamp headers.
Signature Format:
sigBaseString = 'v0:' + timestamp + ':' + JSON.stringify(requestBody)
expectedSignature = HMAC-SHA256(sigBaseString, signingSecret)
TypeScript Implementation:
import crypto from 'crypto';
function verifyOpalSignature(req, signingSecret: string): boolean {
const signature = req.header('X-Opal-Signature');
const timestamp = req.header('X-Opal-Request-Timestamp');
// CRITICAL: Empty body must be {} not empty string
const body = req.body || {};
const sigBaseString = `v0:${timestamp}:${JSON.stringify(body)}`;
const hmac = crypto.createHmac('sha256', signingSecret);
const expectedSignature = hmac.update(sigBaseString).digest('hex');
// CRITICAL: Use timing-safe comparison
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// CRITICAL: Validate timestamp (within 5 minutes)
const now = Math.floor(Date.now() / 1000);
const requestTime = parseInt(timestamp, 10);
if (Math.abs(now - requestTime) > 300) {
throw new Error('Request timestamp too old');
}
Python Implementation:
import hmac, hashlib, json, time
def verify_opal_signature(request, signing_secret: str) -> bool:
signature = request.headers.get('X-Opal-Signature')
timestamp = request.headers.get('X-Opal-Request-Timestamp')
# Validate timestamp
if abs(int(time.time()) - int(timestamp)) > 300:
raise Exception('Request timestamp too old')
body = request.get_json() or {} # Empty body = {}
sig_base_string = f'v0:{timestamp}:{json.dumps(body)}'
expected_signature = hmac.new(
signing_secret.encode(),
sig_base_string.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature) # Timing-safe
Required API Endpoints (Minimum)
These 7 endpoints are required for all connectors:
- GET /status - Health check (returns
{}) - GET /resources - List resources with pagination
- GET /resources/:id - Get single resource details
- GET /resources/:id/access_levels - List available roles/permissions
- GET /resources/:id/users - List users with access to resource
- POST /resources/:id/users - Grant user access to resource
- DELETE /resources/:id/users/:user_id - Revoke user access
All endpoints require app_id query parameter for multi-app support.
Optional Endpoints (Based on Feature Flags)
Groups (9 endpoints, enabled via "Connector Groups"):
- GET /groups, GET /groups/:id
- GET /groups/:id/users, POST /groups/:id/users, DELETE /groups/:id/users/:user_id
- GET /groups/:id/resources, POST /groups/:id/resources, DELETE /groups/:id/resources/:resource_id
- GET /groups/:id/member-groups (if nested groups), POST /groups/:id/member-groups (if nested)
User Provisioning (3 endpoints):
- GET /users, POST /users, DELETE /users/:user_id
Event Ingestion (1 endpoint):
- GET /events
Response Format Standards
List Responses:
{
"resources": [...],
"next_cursor": "base64string"
}
Single Resource:
{
"resource": {...}
}
Errors:
{
"message": "Human-readable error description",
"code": 404
}
HTTP Status Codes:
- 200: Success
- 401: Invalid signature/auth
- 404: Not found
- 429: Rate limit (include
Retry-Afterheader) - 500: Server error
Common Anti-Patterns (MUST AVOID)
1. Incorrect Empty Body Handling
❌ WRONG: sigBaseString = 'v0:' + timestamp + ':'
✅ RIGHT: sigBaseString = 'v0:' + timestamp + ':' + JSON.stringify({})
2. Incorrect Pagination End Marker
❌ WRONG: { resources: [], next_cursor: null }
✅ RIGHT: { resources: [], next_cursor: "" } (empty string)
3. Missing Error Code
❌ WRONG: res.status(404).send("Not found")
✅ RIGHT: res.status(404).json({ message: "Resource not found", code: 404 })
4. SQL Injection Vulnerability
❌ WRONG: `SELECT * FROM resources WHERE app_id = '${appId}'`
✅ RIGHT: Parameterized queries: query('SELECT * FROM resources WHERE app_id = $1', [appId])
5. Not Using Timing-Safe Comparison
❌ WRONG: signature === expectedSignature
✅ RIGHT: crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))
6. console.log in Production
❌ WRONG: console.log('Fetching resources')
✅ RIGHT: Structured logging: logger.info('Fetching resources', { app_id: appId })
Gold Standard Requirements
Security (CRITICAL)
- ✅ HMAC signature verification on all endpoints
- ✅ Timestamp validation (within 5 minutes)
- ✅ Input validation (app_id, resource_id, user_id, email)
- ✅ Parameterized database queries (no string concatenation)
- ✅ Rate limiting (Redis-based, per-app)
- ✅ No secrets in logs or error messages
Architecture
- ✅ Separate handlers, services, middleware layers
- ✅ TypeScript strict mode OR Python type hints
- ✅ Connection pooling (database, Redis)
- ✅ Cursor-based pagination (efficient for large datasets)
- ✅ Caching for static data (access levels)
Error Handling
- ✅ Centralized error handler
- ✅ Standard error format on all endpoints
- ✅ Proper HTTP status codes
- ✅ No sensitive data in error messages
- ✅ Errors logged with context
Testing
- ✅ 90%+ code coverage
- ✅ Unit tests (handlers, services, utilities)
- ✅ Integration tests (full HTTP request/response)
- ✅ Security tests (signature verification, SQL injection, XSS)
- ✅ Performance tests (response time < 2s, concurrent requests)
- ✅ Contract tests (Opal API spec compliance)
Documentation
- ✅ README with setup instructions
- ✅ API documentation
- ✅ .env.example with all variables
- ✅ Inline code comments for complex logic
Success Criteria
A connector is production-ready when:
- All required endpoints implemented and tested
- HMAC signature verification working (401 on invalid signature)
- Test coverage >= 90% overall
- No SQL injection vulnerabilities (parameterized queries only)
- Rate limiting configured (429 with Retry-After header)
- Proper error format on all endpoints (
{ message, code }) - Pagination returns empty string on last page (
next_cursor: "") - Response time < 2 seconds for all endpoints
- No PII in logs
- CI/CD pipeline passing (lint, type-check, tests)
Verification Steps (Run Before Completion)
# 1. Code quality
npm run lint # No errors
npm run type-check # No errors
# 2. Testing
npm run test:coverage # >= 90%
# 3. Security tests (must pass)
# - Test invalid signature → must return 401
# - Test expired timestamp → must return 401
# - Test SQL injection in app_id → must be safe
# - Test XSS in resource name → must be escaped
# 4. Integration tests
# - Test pagination returns empty string on last page
# - Test error format matches spec
# - Test all required endpoints return 200
# 5. Manual testing
# - Start connector locally
# - Test with Postman/curl
# - Verify signature verification works
# - Verify pagination works across multiple pages
Inputs Required from User
- App name: Target system (e.g., "Datadog", "Salesforce", "GitHub")
- Tech stack: TypeScript/Node.js or Python
- Optional features:
- Groups support?
- Nested groups?
- Nested resources?
- User provisioning?
- Event ingestion?
- Target system details:
- API base URL
- Authentication method
- Available resources/permissions
Supporting Files
This skill includes detailed reference files:
- api-reference.md: Complete endpoint specifications with request/response examples, query parameters, and edge cases
- gold-checklist.md: Full production readiness checklist covering security, performance, testing, documentation, and DevOps
- testing-patterns.md: Comprehensive testing guide with unit, integration, security, and performance test examples
- implementation-examples.md: Full code examples for auth middleware, pagination, caching, error handling, and database queries
External References
- Opal API Specification: https://docs.opal.dev/docs/api-spec
- Connector Development Guide: https://docs.opal.dev/docs/how-to-create-your-own-connector
- Reference Implementation: https://github.com/opalsecurity/opal-datadog-connector (production-ready example)
Workflow
- Discovery: Ask user for app name, tech stack, optional features
- Planning: Create implementation plan with all endpoints
- Scaffolding: Generate project structure (handlers, middleware, services, tests)
- Core Implementation: Implement auth middleware, then required endpoints
- Optional Features: Add groups/provisioning/events if requested
- Testing: Generate comprehensive test suite (90%+ coverage)
- Documentation: Generate README, API docs, .env.example
- Verification: Run all verification steps
- Audit: Score against gold standard checklist
For Auditing Existing Connectors
When auditing, check against gold checklist in this order:
- Security (CRITICAL): Signature verification, input validation, SQL injection
- API Compliance: All required endpoints, response format, pagination
- Testing: Coverage percentage, test types (unit, integration, security)
- Code Quality: TypeScript strict mode, linting, no console.log
- Performance: Connection pooling, caching, response times
- Documentation: README, API docs, inline comments
Generate compliance report with:
- Overall score (0-100%)
- Critical issues (must fix before production)
- High priority issues (should fix soon)
- Improvement roadmap with effort estimates
For Refactoring to Gold Standards
When refactoring, prioritize in this order:
- Security fixes (CRITICAL - must fix): Add/fix signature verification, input validation, fix SQL injection
- API compliance (HIGH): Add missing endpoints, fix response format, fix pagination
- Testing (HIGH): Increase coverage to 90%+, add security tests
- Code quality (MEDIUM): Add TypeScript strict mode, remove console.log, proper error handling
- Performance (MEDIUM): Add caching, optimize queries, add rate limiting
- Documentation (LOW): Update README, add API docs, add comments
Always create backup branch before refactoring: git checkout -b gold-standard-refactor