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 organizationId parameter 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.

ActionAdminClientViewer
Organization and certificate settingsAllowedNot allowedNot allowed
Member managementAllowedNot allowedNot allowed
API key managementAllowedNot allowedNot allowed
Create / update / cancel invoicesAllowedAllowedNot allowed
Read invoices, status, and analyticsAllowedNot allowedAllowed
Read audit trailAllowedNot allowedAllowed
Cross-tenant reads
Return 404, never 403: 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 429 response with a Retry-After header, 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.