FilPass & OpenCerts
Package: soq-filpass-opencerts - Permissions: 90190-90194 - Status: Implemented with mock adapter; production API pending FilPass documentation.
What This Module Does
FilPass adds an external verifiable credential layer on top of SOQ's existing internal certificate system. SOQ still creates its normal certificate first. When enabled, the observer creates one pending row in filpass_credentials; the scheduler later sends it to FilPass.
Checkout, quiz completion and course completion never call FilPass directly, so FilPass outages do not block learners.
Admin Screens
- Settings (
/admin/filpass): enable issuance, go-live date, environment, credentials, issuer name and template IDs. - Issuance log (
/admin/filpass/logs): pending/issued/failed/revoked/expired rows, payload preview, retry, sync now and revoke.
Who Uses This Page
| Role | What they do | Permissions needed |
|---|---|---|
| System admin | Install seed, configure credentials, set issue date and template mapping. | admin_filpass_settings |
| Operations admin | Check issuance log, preview payloads, run Sync now. | admin_filpass_logs, optionally admin_filpass_retry |
| Compliance admin | Investigate revoked or expired credentials. | admin_filpass_logs |
| Senior admin | Revoke issued credentials. | admin_filpass_revoke |
Pre-processing: Set Up FilPass Before Touching SOQ
Do this with FilPass first, then copy the values into /admin/filpass. Keep sandbox and production values separate.
| Step | In FilPass | Value you need for SOQ | Where it goes in SOQ |
|---|---|---|---|
| 1 | Create or request the SOQ issuer/organization account. | Legal issuer name, normally SOQ International Academy. | Issuer name |
| 2 | Request API access for the environment. | Sandbox or production API base URL, without a trailing slash. | API base URL |
| 3 | Create an API application / integration credential. | Preferred: API key / bearer token. Alternative: Client ID + Client secret. | API key, or Client ID + Client secret |
| 4 | Create credential templates for each SOQ certificate type. | Template IDs for course, quiz, and bundle. | Template IDs mapping |
| 5 | Register SOQ callback/webhook endpoint. | https://<your-soq-domain>/webhooks/filpass | FilPass webhook/callback URL field |
| 6 | Choose a webhook signing secret. | A long random shared secret. | Webhook secret |
| 7 | Confirm lifecycle event payload. | document_id or filpass_document_id, and status = revoked or expired. | Webhook handling |
| 8 | Confirm issuance response fields. | document_id or id, and verification_url or verify_url. | Issuance sync |
SOQ posts to POST {API base URL}/credentials, reads GET {API base URL}/credentials/{document_id}, and revokes with POST {API base URL}/credentials/{document_id}/revoke.
Authentication is sent as Authorization: Bearer <API key> when API key is filled. If API key is empty, SOQ uses HTTP Basic Auth with Client ID + Client secret.
Webhook signature expected by SOQ: X-FilPass-Signature: sha256=<hex_hmac_sha256_of_raw_body_using_webhook_secret>.
Use the exact public HTTPS URL displayed under Webhook URL on /admin/filpass. For sandbox testing from a local machine, expose SOQ through HTTPS using a tunnel or staging domain and register that HTTPS URL in FilPass.
Before Enabling
- Database installed:
filpass_credentialstable exists. - Seed installed: sections 90190-90194 exist and admin has permissions.
- Scheduler installed: server runs
php artisan schedule:runevery minute. - Issue date decided: old certificates are not backfilled automatically.
- Template IDs ready: quiz, course and bundle template IDs are known.
- Environment selected: use mock for local/UAT without FilPass; use sandbox only after FilPass-side setup is complete.
- API credential saved: fill either API key or both Client ID and Client secret. Client ID is also required in sandbox/production mode.
- Webhook registered:
{APP_URL}/webhooks/filpasswith the same HMAC secret saved in SOQ. - Response contract confirmed: FilPass issuance response includes
document_id/idandverification_url/verify_url. - Privacy reviewed: keep Include NRIC/FIN off for v1.
Field Guide
| Field | Required? | What to enter | What it affects |
|---|---|---|---|
| Enable FilPass issuance | Yes for live | Turn on only after issue date and mapping are ready. | New certificates can be queued. |
| Auto issue new certificates | Usually yes | Keep on for automatic issuance. | Observer creates pending rows. |
| Issue from date | Yes when enabled | Go-live date. | Certificates before this date are ignored. |
| Environment | Yes | mock, sandbox, or production. | Chooses mock or live client. |
| Credentials | Live/sandbox | API base URL, Client ID/secret or API key. | Authenticates FilPass API calls. |
| Webhook secret | Yes for webhook | Shared HMAC secret configured at FilPass. | Verifies POST /webhooks/filpass. |
| Template IDs | Per type | FilPass template ID for quiz, course and bundle. | Missing mapping fails the row before API call. |
How The Queue Works
- A learner earns a normal SOQ certificate.
- The FilPass observer checks
enabled,auto_issueandissue_from_date. - If eligible, SOQ inserts one
filpass_credentialsrow withstatus = pending. soq:filpass-syncruns every 5 minutes and processes pending plus retryable failed rows.- Successful responses save document ID, verifier URL, PDF URL, OpenCerts hash and
status = issued. - Signed webhooks update rows to
revokedorexpired.
How To Enable In UAT
- Run
php artisan migrate. - Run
php artisan soq:seed-filpass. - Open
/admin/filpass. - Set Environment = mock.
- Set Issue from date = today.
- Fill template IDs such as
mock_course,mock_quiz,mock_bundle. - Turn on Enable FilPass issuance and Auto issue new certificates.
- Create a new SOQ certificate, then open
/admin/filpass/logsand click Sync now.
UAT Script
| Step | Action | Expected result |
|---|---|---|
| 1 | Save mock settings. | Settings saved; secrets are not displayed back. |
| 2 | Complete a course or quiz as a student. | Internal SOQ certificate can be downloaded. |
| 3 | Open /admin/filpass/logs. | A pending row appears for the certificate ID. |
| 4 | Click Preview payload. | Payload includes source, issuer, template, recipient and programme data. |
| 5 | Click Sync now. | Row becomes Issued with FP-MOCK-* document ID. |
| 6 | Open learner achievements and public validation. | FilPass status and verifier link are visible. |
Daily Operations
- Check
/admin/filpass/logsfor Failed rows during UAT and after go-live. - Preview payload after changing template IDs.
- After a FilPass outage, retry one row first, then Retry all failed.
- For learner complaints, search by certificate ID and compare internal certificate, FilPass row and verifier link.
Buttons And Actions
| Action | What it does | Safe to repeat? |
|---|---|---|
| Preview payload | Builds payload without calling FilPass. | Yes |
| Retry | Resets a failed row to pending and attempts to 0. | Yes, after fixing cause |
| Retry all failed | Resets all failed rows to pending. | Use after known outage/config fix |
| Sync now | Runs soq:filpass-sync immediately. | Yes |
| Revoke | Calls FilPass revoke endpoint and marks row revoked. | No, use with approval |
Production Go-Live
Production requires official FilPass API documentation and credentials. Confirm endpoint paths, authentication, response fields, rate limits and webhook signature format before changing environment to production.
In FilPass production, create the SOQ issuer/integration credential and production templates, then register the exact webhook URL shown in SOQ: {PROD_URL}/webhooks/filpass.
In /admin/filpass, enter production API base URL, Client ID, and either API key or Client secret. Save the same webhook signing secret in both FilPass and SOQ.
Make sure php artisan schedule:run is installed every minute before running the first live certificate.
Do not switch config/soq_modules_pitch.php from coming_soon until the production FilPass credential flow has been tested with real credentials.
Status Meanings
| Status | Meaning | Operator action |
|---|---|---|
| Pending | Waiting for cron or Sync now. | Wait 5 minutes or click Sync now. |
| Issued | FilPass returned document ID and verifier URL. | Verify external link. |
| Failed | Payload, config or API error. | Read error, fix config, Retry. |
| Skipped | Certificate missing or intentionally not sent. | Usually no action. |
| Revoked | Admin/API/webhook marked it revoked. | Confirm reason and replacement policy. |
| Expired | FilPass webhook marked it expired. | Confirm if re-issuance is needed. |
Incident Playbooks
Pending Rows Do Not Move
- Confirm scheduler is running:
php artisan schedule:list. - Click Sync now.
- Check module enabled, issue date and credential configuration.
- If the row is new, wait for the short settle window.
Webhook Returns 403
- Compare FilPass webhook secret with SOQ
webhook_secret. - Confirm FilPass signs the raw request body with HMAC SHA-256.
- Confirm header format:
X-FilPass-Signature: sha256=<signature>. - Rotate the secret if it may have leaked.
Troubleshooting
- No row appears: module disabled, auto issue off, issue date in the future, or old certificate.
- Template missing: fill template ID for the certificate type and retry.
- Missing credentials: live/sandbox mode needs API base URL and credentials.
- Webhook 403: signature does not match
webhook_secret.
Security And Privacy Notes
- Secrets are encrypted in
soq_filpass_settingsand never displayed back. - Changing
APP_KEYmakes encrypted secrets unreadable; re-enter FilPass secrets afterward. - The webhook route is CSRF-exempt but HMAC verification is mandatory.
- v1 does not send NRIC/FIN. Do not repurpose identity scan uploads as plain identity numbers.
Quick Command Reference
php artisan soq:seed-filpass
php artisan soq:filpass-sync --limit=50
php artisan schedule:list
php artisan migrate:status --pending