E-Invoicing Security in Morocco: Platform Protection
EFact processes legally binding tax documents on behalf of Moroccan businesses. Security is not an add-on feature: it is the core constraint around which the platform was built.
In short
EFact encrypts secrets at rest using AES-256-GCM (including signing certificate passwords), enforces strict multi-tenant isolation between organizations, and records every status transition in an append-only audit trail. Tax documents are archived for 10 years in immutable storage, in compliance with Moroccan tax regulations.
DGI integration status
The national DGI e-invoicing platform is not yet open to integrations. Any mention of "DGI" on this page currently refers to our DGI simulator, which reproduces the official clearance flow (submission, signature validation, reference assignment, QR code, callbacks) under the same security guarantees. Transitioning to the official platform will require zero client-side changes.
Authentication
Two separate authentication planes, isolated at HTTP filter level so neither can weaken the other.
API Keys - machine to machine
- Format
efact_sk_followed by 256 bits of cryptographically secure randomness (CSPRNG, Base64url). The recognizable prefix enables automated leak detection by code secret scanners.- Storage
- Never stored in plaintext: only the SHA-256 hash is persisted. Even in the event of database compromise, no usable key can be extracted.
- Display
- The dashboard only displays
efact_sk_and the first 6 characters. The full key is shown once only, upon creation. - Transport
- Exclusively via
Authorization: Bearer. Never in URLs, query strings, or request bodies - thus never exposed in access logs, browser history, or proxies. - Scope
- The key resolves the organization server-side. No user-supplied
organizationIdparameter is accepted: a key can only access data within its own organization. - Revocation
- Instant revocation from the dashboard. Soft-delete: the key ceases authenticating immediately while retaining records for the audit trail.
- Observability
- Each key tracks
last_used_at: dormant or suspicious keys are easily spotted and rotated.
Dashboard - human users
- OpenID Connect
- Short-lived JWT tokens validated on every request: signature, issuer, and expiration verified with the identity provider.
- Stateless
- No server-side sessions, eliminating session fixation attack vectors.
- Inherited Controls
- Delegating identity to OIDC providers inherits password policies and brute-force detection.Planned Self-service MFA/TOTP and SSO federation.
Planes separation
The API runs distinct security filter chains: JWT validation only runs on dashboard routes, while the billing API authenticates API keys directly. Any route not explicitly declared in either chain is denied by default - new endpoints remain unreachable until deliberately exposed.
Authorization & Multi-Tenant Isolation
Every organization-scoped request passes through a centralized check verifying tenant membership and role permissions. Role-to-permission mappings are hardcoded in source code, non-modifiable at runtime: policy is code, not data.
| Action | Admin | Client | Viewer |
|---|---|---|---|
| Organization and certificate settings | Allowed | Not allowed | Not allowed |
| Member management | Allowed | Not allowed | Not allowed |
| API key management | Allowed | Not allowed | Not allowed |
| Create / update / cancel invoices | Allowed | Allowed | Not allowed |
| Read invoices, status, and analytics | Allowed | Not allowed | Allowed |
| Read audit trail | Allowed | Not allowed | Allowed |
- Cross-tenant reads
- Return
404, never403: the API never confirms the existence of a resource belonging to another organization. - Identifiers
- All primary keys are UUIDs - non-sequential, unpredictable. Enumeration attacks are eliminated by design.
Encryption
In transit and at rest, without degraded fallback modes.
- In transit
- TLS throughout: the public API is HTTPS-only. The DGI transmission channel is engineered for mutual TLS (mTLS) with client certificates on dedicated SSL bundles per environment - currently routing to the DGI simulator.
- At rest
- Stored secrets (e.g. signing certificate passwords) are encrypted using AES-256-GCM: random 96-bit IV per encryption, 128-bit authentication tag (tampering is detected cryptographically), and a versioned format (
v1:) ready for master key rotation. - Master key
- Never touches codebase or database: injected via environment variable. If missing or malformed, the application refuses to boot. No degraded plaintext storage mode exists.
Abuse prevention
- Rate limiting
- 300 requests/minute per API key (token-bucket). Exceeding limits returns a structured
429response with aRetry-Afterheader, honored automatically by official SDKs (exponential back-off + jitter). - Edge validation
- Request bodies are validated against strict schemas (15-digit ICE, ISO currency codes, date formats) and rejected with field-level errors prior to business logic execution.
- Sanitized pagination
- Sorting and pagination parameters are whitelisted server-side, preventing property injection via sort expressions.
- Uniform error envelope
- A consistent format for all failures, including authentication:
{ code, message, data, errors }. No stack traces or raw server error leaks.
DGI callbacks
Status callbacks are treated as untrusted inputs. They are currently issued by our DGI simulator, with identical guarantees to those specified for the official platform.
- Signature
- Each callback is signed with HMAC-SHA256 across the raw request body; verification uses constant-time comparison.
- Anti-replay
- Each callback carries a timestamp verified against maximum allowable clock skew.
- Idempotency
- Each callback includes a unique event ID; events are persisted and deduplicated. Replayed callbacks never apply state transitions twice.
Document integrity
The core product pipeline itself constitutes an integrity guarantee.
- Normalization
- Invoices are normalized into UBL 2.1 XML and validated against the official XSD before any subsequent processing.
- Fingerprint
- Canonical XML is hashed using SHA-256. This hash provides cryptographic proof of integrity and document idempotency across the entire lifecycle.
- Signature
- XAdES electronic signature (RSA/SHA-256) applied with the organization's PKCS#12 certificate.
- Certificates
- Validated upon upload (format, password, usable key material); passwords are stored exclusively encrypted with AES-256-GCM.
- Fail-closed
- If any cryptographic step fails, the entire transaction rolls back. Invoices cannot exist in a half-signed state.
Audit trail
- Append-only log
- Every status transition writes an immutable audit record: previous status, new status, actor, reason code, human-readable reason, and structured metadata.
- Read-only
- The audit trail is readable via API (Admin and Viewer roles), never mutable. It satisfies the traceability requirements of Moroccan tax compliance (Article 145-IX of the CGI).
- Key retention
- Revoked keys are preserved, not deleted, to maintain audit history integrity.
Secrets & operational hygiene
- No hardcoded secrets
- All production secrets (master encryption keys, integration credentials) are injected via environment variables - never committed in code or configuration files.
- Startup guardrails
- The production profile refuses to boot if any secret is missing or remains a development placeholder. Misconfigured deployments fail loudly at startup. Only secret names are logged, never values.
- Log redaction
- XML signatures, QR payloads, DGI responses, passwords, and private PEM keys are masked by pattern in the logging layer prior to writing to any log appender.
- SDK discipline
- Official SDKs follow the same standard: secret keys are never logged, never included in URLs, and never exposed in error messages.
Infrastructure & availability
- Stateless API
- Zero session state: horizontally scalable behind load balancers.
- Health probes
- Dedicated health checks monitoring DGI connectivity and stalled invoice detection.
- Metrics
- Continuously collected for uninterrupted operational monitoring.
- Self-healing
- Stalled or transiently failed submissions are automatically re-queued; blocked transmissions are re-polled. See Architecture.
Compliance
- Legal framework
- Engineered for Article 145-IX of Morocco's CGI and the DGI 2026 e-invoicing clearance mandate.
- Mandated formats
- UBL 2.1 XML and XAdES digital signatures, as required by the regulatory reform.
- Archiving
- 10-year statutory legal archiving of invoice artifacts.
- External audits Planned
- Formal third-party penetration testing, coordinated vulnerability disclosure, and SOC 2 attestation as platform volume scales across the 2026-2029 rollout.
Report a vulnerability
Write to contact@itzenata.com. We request responsible disclosure from researchers and acknowledge reports promptly.
Frequently asked questions
How does EFact protect signing keys and certificates?
Secrets, including the signing certificate password, are encrypted at rest using AES-256-GCM. The master key comes from an environment variable that is never version-controlled, and the application refuses to start if it is missing. No plaintext secrets are logged, and keys are strictly isolated per organization.
Is organization data isolated from other organizations?
Yes. EFact enforces strict multi-tenant isolation: every request is scoped to an organization, and a client can only access its own invoices, keys, and settings. Roles (admin, client, viewer) further restrict permitted actions within an organization.
How long are invoices archived?
Tax documents are archived for 10 years in immutable storage, as required by Moroccan regulations. Every invoice status transition is recorded in an append-only audit log, guaranteeing a reliable audit trail required for DGI compliance.