Permission System - Certificate Request & Signing Separation
Overview
The PKI-as-a-Service application implements a granular permission system that enforces separation of duties between certificate requesters and certificate approvers. This prevents users from self-approving their own certificate requests, a critical security requirement for enterprise PKI deployments.
Permission Architecture
Two-Layer Permission Model
The system uses two complementary permission layers:
- Spatie Laravel Permission (Global): Application-wide permissions managed through roles
- CA Group Permissions (Per-CA): Fine-grained permissions specific to individual Certificate Authorities
Key Principles
- Separation of Duties: Requesters cannot approve their own certificates
- Least Privilege: Users receive only the minimum permissions required for their role
- Audit Trail: All permission changes and usage are logged for compliance
Certificate Permissions (New Model)
request-certificates
Purpose: Submit certificate signing requests (CSR) to a Certificate Authority
Allows: - Submit new certificate requests via web UI or API - Upload CSR files for processing - Request certificates through ACME protocol - View status of own certificate requests
Does NOT Allow: - Approve or sign certificate requests - Issue certificates without approval (unless CA policy allows automatic approval)
Typical Roles:
- acme-client (ACME automated requests)
- Requesters in approval-based workflows
sign-certificates
Purpose: Validate, approve, and sign certificate requests
Allows: - Review pending certificate requests - Approve or reject certificate requests - Sign CSRs to issue certificates - Configure CA approval policies
Does NOT Allow:
- Submit certificate requests (must have request-certificates separately)
Typical Roles:
- pki-manager (PKI administrators)
- certificate-operator (Certificate validators)
Combined Permissions
Some roles require both permissions to operate normally:
Example: PKI Manager
// Has BOTH permissions
'request-certificates' // Can submit requests
'sign-certificates' // Can approve and sign
This enables PKI managers to perform all certificate operations while still maintaining separation when strict approval workflows are required.
Protocol-Specific Permissions (OpenVPN, Windows 802.1x)
create-openvpn-certificates
Purpose: Generate OpenVPN client certificates for a specific Certificate Authority
Allows: - Generate OpenVPN client certificates with .ovpn configuration files - Access OpenVPN template editor for the CA - Download .ovpn profiles for existing certificates - Configure OpenVPN-specific certificate extensions (clientAuth)
Does NOT Allow:
- Generate certificates for other CAs without explicit permission
- Create OpenVPN server certificates (requires sign-certificates)
- Modify CA settings or templates without additional permissions
Security Model: - CA-specific: Permission is granted per Certificate Authority via CA Groups - Defense in depth: Multi-tenant isolation prevents cross-CA access even without permission - Audit trail: All OpenVPN certificate generation is logged with user ID and IP
Typical Use Case: VPN administrators who need to issue client certificates for their organization's VPN infrastructure without full PKI management rights.
Example Configuration:
// CA Group: "Company VPN Team"
// Permission: 'create-openvpn-certificates'
// Members: vpn-admin@company.com
// This user can ONLY generate OpenVPN certificates for THIS CA
// They cannot access other CAs or perform other certificate operations
create-windows-certificates
Purpose: Generate Windows 802.1x EAP-TLS certificates for network authentication
Allows: - Generate EAP-TLS client certificates for Windows workstations - Export certificates in PKCS#12 format with password protection - Generate WiFi XML profiles for automatic deployment - Create mobile configuration profiles for iOS/macOS
Does NOT Allow: - Generate certificates for other CAs without explicit permission - Modify certificate templates or CA settings
Security Model: - CA-specific: Permission is granted per Certificate Authority via CA Groups - Enterprise isolation: Ensures IT teams can only manage their own organization's devices - Compliance: Supports BYOD policies with proper access segregation
Typical Use Case: Enterprise IT administrators managing network authentication certificates for corporate devices.
Multi-Tenant OpenVPN Scenario
Problem: Multiple companies share the PKI infrastructure, each needs isolated VPN certificate management.
Solution: CA Groups with protocol-specific permissions
| CA | Organization | CA Group | Permission | Users |
|---|---|---|---|---|
| CA-VPN-A | Company A | "VPN Team A" | create-openvpn-certificates |
alice@companya.com |
| CA-VPN-B | Company B | "VPN Team B" | create-openvpn-certificates |
bob@companyb.com |
| CA-WEB | Shared | "Web Admins" | request-certificates only |
charlie@shared.com |
Result: - ✅ Alice can generate OpenVPN certificates only for CA-VPN-A - ✅ Bob can generate OpenVPN certificates only for CA-VPN-B - ❌ Charlie cannot generate OpenVPN certificates (wrong permission) - ✅ Complete isolation between organizations (defense in depth)
Code Implementation:
// OpenVpnController::storeClient() - Line 63-71
$user = auth()->user();
$caGroup = $ca->groups()
->whereHas('users', fn($q) => $q->where('user_id', $user->id))
->first();
if (!$caGroup || !$caGroup->hasPermission('create-openvpn-certificates')) {
abort(403, 'You do not have permission to create OpenVPN certificates for this CA');
}
Migration from Legacy create-certificates Permission
What Changed?
Before (v0.1):
- Single permission: create-certificates
- No separation of duties
- Users could approve their own certificates
After (v0.2-alpha):
- Two permissions: request-certificates + sign-certificates
- Enforced separation of duties
- Approval workflows properly segregated
Automatic Migration
When upgrading to v0.2-alpha, the migration automatically:
- Creates new permissions:
request-certificatesandsign-certificates - Updates existing roles: Users with
create-certificatesreceive BOTH new permissions - Updates CA Groups: Replaces
create-certificateswith both new permissions - Preserves access: No users lose access during migration
Migration SQL Logic:
-- Users with create-certificates get BOTH new permissions
UPDATE user_permissions
SET permissions = ['request-certificates', 'sign-certificates']
WHERE permissions CONTAINS 'create-certificates';
Rollback Support
The migration is fully reversible:
# Rollback to legacy permission model
php artisan migrate:rollback
This restores create-certificates and removes the split permissions.
Permission Matrix
| Permission | Requester | Validator | VPN Admin | PKI Manager | Admin | ACME Client |
|---|---|---|---|---|---|---|
request-certificates |
✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
sign-certificates |
❌ | ✅ | ❌ | ✅ | ✅ | ❌ |
create-openvpn-certificates |
❌ | ❌ | ✅ | ✅ | ✅ | ❌ |
create-windows-certificates |
❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
view-certificates |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
revoke-certificates |
❌ | ✅ | ❌ | ✅ | ✅ | ❌ |
download-certificates |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
CA Group Permissions (Per-CA Granularity)
CA Groups allow even finer control by restricting permissions to specific Certificate Authorities.
Available CA Group Permissions
'view-ca' => 'View CA details'
'view-certificates' => 'View certificates from this CA'
'request-certificates' => 'Submit certificate requests (CSR)'
'sign-certificates' => 'Validate and sign certificates'
'create-openvpn-certificates' => 'Generate OpenVPN client certificates'
'create-windows-certificates' => 'Generate Windows 802.1x certificates'
'revoke-certificates' => 'Revoke certificates from this CA'
'download-certificates' => 'Download certificates from this CA'
'view-crl' => 'View and download CRLs from this CA'
'manage-ca-settings' => 'Modify CA settings'
Example: Multi-Tenant Scenario
Company A - Internal CA:
- Group: "Company A Requesters"
- Permission: request-certificates
- Members: Company A employees
- Group: "Company A Validators"
- Permission:
sign-certificates - Members: Company A security team
Company B - External CA:
- Group: "Company B Partners"
- Permission: request-certificates only
- Members: External partners
- Approval: Manual approval required
Approval Workflows
Automatic Approval
- Requires:
request-certificatespermission - CA Policy:
approval_mode=automatic - Use Case: ACME automated issuance, low-risk certificates
Manual Approval
- Requester:
request-certificatespermission - Approver:
sign-certificatespermission - CA Policy:
approval_mode=manual - Use Case: High-security certificates, external partners
Policy-Based Approval
- Requester:
request-certificatespermission - System: Evaluates CA Access Policies
- Approver:
sign-certificatespermission (if required) - CA Policy:
approval_mode=policy - Use Case: Complex rules (IP restrictions, OAuth groups, time-based)
Implementation Details
Permission Checks in Controllers
Certificate Request Submission:
// Check permission before accepting CSR
if (! $user->can('request-certificates')) {
abort(403, 'You do not have permission to request certificates');
}
Certificate Signing:
// Check permission before signing
if (! $user->can('sign-certificates')) {
abort(403, 'You do not have permission to sign certificates');
}
CA Group Permission Check:
// Check CA-specific permission
$caGroup = $ca->groups()->whereHas('users', fn($q) => $q->where('user_id', $user->id))->first();
if (! $caGroup || ! $caGroup->hasPermission('sign-certificates')) {
abort(403, 'You do not have sign permission for this CA');
}
Audit Logging
All permission-related events are logged:
- Permission grant/revoke
- Certificate request submissions
- Certificate approvals/rejections
- Permission check failures (403 errors)
Example Audit Log:
{
"event": "certificate.requested",
"user_id": 42,
"ca_id": 5,
"permission_used": "request-certificates",
"approval_required": true,
"ip_address": "192.168.1.100",
"timestamp": "2025-10-15T08:00:00Z"
}
Best Practices
1. Separate Roles for Separation of Duties
❌ Avoid: Giving both request and sign to all users
✅ Recommended: Create separate "Requester" and "Validator" roles
2. Use CA Groups for Multi-Tenant Isolation
❌ Avoid: Global sign-certificates permission for all CAs
✅ Recommended: CA Group permissions per tenant/department
3. Automatic Approval for Low-Risk Scenarios Only
❌ Avoid: Automatic approval for high-security CAs ✅ Recommended: Manual or policy-based approval for sensitive certificates
4. Regular Permission Audits
✅ Recommended: Quarterly review of user permissions ✅ Recommended: Automated alerts for permission changes ✅ Recommended: Compliance reports for separation of duties
Compliance & Standards
This permission model aligns with:
- SOC 2 Type II: Separation of duties controls
- ISO 27001: Access control requirements (A.9)
- NIST 800-53: AC-5 (Separation of Duties)
- PCI DSS: Requirement 7.1 (Least Privilege)
- WebTrust for CAs: Baseline Requirements Section 5.2
Troubleshooting
"Permission Denied" When Submitting Certificate Request
Cause: User lacks request-certificates permission
Solution:
# Check user permissions
php artisan permission:show {user_email}
# Grant permission via role
php artisan permission:assign {user_email} request-certificates
"Cannot Approve Own Certificate Request"
Expected Behavior: Separation of duties prevents self-approval
Solution: Assign a different user with sign-certificates to approve
Migration Issues
Problem: Permissions not migrated correctly
Diagnosis:
# Check migration status
php artisan migrate:status
# Verify permissions in database
SELECT * FROM permissions WHERE name IN ('request-certificates', 'sign-certificates');
Fix:
# Re-run migration
php artisan migrate:refresh --path=database/migrations/2025_10_15_074114_split_create_certificates_permission.php
Related Documentation
- CA Access Policies - IP/domain/OAuth-based access control
- CSR Issuance Workflow - Certificate request process
- User Management - Role assignment and user administration
- Audit Logging - Compliance logging and reporting
Version History
| Version | Date | Changes |
|---|---|---|
| v0.2-alpha | 2025-10-15 | Introduced request-certificates + sign-certificates splitAdded protocol-specific permissions: create-openvpn-certificates, create-windows-certificatesImplemented CA-specific permission enforcement for OpenVPN |
| v0.1 | 2025-09-28 | Legacy create-certificates permission |
Vous n'avez pas envie de la manager ?
Découvrir notre offre PKI As A Service