Mekovault
Technical governance

How Mekovault is built and operated

Reference for IT, security, compliance and audit teams evaluating Mekovault before signing. It covers infrastructure, the identity model, tenant isolation, how directory credentials are handled, and what is still in progress.

Last reviewed: September 9, 2026Descriptive document of current operational controls. It is not a formal certification.

At a glance

Region
AWS Lightsail, us-east-1 (Northern Virginia)
Topology
4 machines on a private network; only one exposed to the Internet
Customer secrets
Self-hosted Infisical, one project per tenant
Database
PostgreSQL 16 with Row-Level Security by company_id
Session
15-minute RS256 JWT + 30-day refresh in an HttpOnly cookie
MFA
TOTP, required for sensitive operations
Credential usage
Immutable per-operation log, exportable and signed
Administrative access
Tailscale only; no public SSH

01Infrastructure

Mekovault runs on AWS Lightsail in us-east-1, on four machines connected by a private network. Only one of them receives Internet traffic.

HostRoleServicesExposure
mekovault-appApplicationnginx, Next.js, FastAPI services, addonsOnly exposed host: ports 80/443 behind Cloudflare
mekovault-dataDataPostgreSQL 16, Redis (2 instances), RabbitMQPrivate network only
mekovault-vaultSecretsSelf-hosted Infisical, one project per tenantPrivate network only
mekovault-obsObservabilityGrafana, Loki, Prometheus, Tempo, OpenTelemetry CollectorPrivate network only
Production machines
InternetCloudflare (80/443)ONLY EXPOSED POINTmekovault-appnginx 路 web 路 svc-* 路 addons80/443PRIVATE NETWORK (NO PUBLIC IP)mekovault-dataPostgreSQL 16 路 Redis 脳2 路 RabbitMQmekovault-vaultInfisical 路 1 project / tenantmekovault-obsGrafana 路 Loki 路 Prometheus 路 Tempo 路 OTelTailscaleadministration
Production topology. Only mekovault-app receives Internet traffic, through Cloudflare. The other machines have no public IP and are administered over Tailscale.
  • Administration exclusively over Tailscale (WireGuard). No host has SSH open to the Internet.
  • ufw firewall active on every machine with a default-deny policy.
  • Internal services (PostgreSQL, Redis, RabbitMQ, Infisical, Grafana and the FastAPI processes) listen on loopback or the private interface. nginx is the only process serving public traffic.
  • Cloudflare terminates TLS and filters traffic before it reaches nginx.

02Service architecture

The web interface is a Next.js 16 application. The backend is a set of FastAPI services on Python 3.12 with async SQLAlchemy, each with a narrow responsibility.

ServiceResponsibility
svc-authAuthentication, sessions, MFA and password reset
svc-tenancyCompanies, memberships, roles, resellers and tenant deletion
svc-requestsJoiner, mover and leaver requests; approval flow
svc-ticketsSupport tickets and their follow-up
svc-billingPlans, subscriptions and invoicing
svc-notificationsEmail and user notifications
addonsConnector modules. Example: super-workspace, which operates on Google Workspace
Backend services

Events and background jobs

  • Services communicate through events on RabbitMQ, using the topic exchange mekovault.events.
  • Heavy work (provisioning, deletions, exports) is recorded in a job ledger in PostgreSQL and executed by a single worker.
  • Each job retries with exponential backoff. Its steps are idempotent: re-running a completed step does not produce duplicate effects on the directory.
  • When a job exhausts its retries an alert is raised and the job stays visible with its last error for manual intervention.

03Identity and session

Mekovault users (IT administrators, approvers, resellers) authenticate with Google OAuth or with email and password. The session is designed so that a stolen token is short-lived and revocable.

MechanismDetail
Sign-in methodsOAuth with Google, or email and password
Access tokenJWT signed with RS256, 15-minute lifetime, with role and MFA-state claims
Refresh token30-day lifetime. Lives only in an HttpOnly cookie (unreachable from JavaScript). Rotated on every use and individually revocable by jti in Redis. Inherits the session's MFA state and re-validates the user's company membership on every renewal.
MFATOTP (standard authenticator apps). Limit of 5 attempts per minute; 15-minute lockout after 10 consecutive failures.
Sensitive operationsRequire a session with verified MFA, even if the user is already authenticated.
Password resetSingle-use token with a 30-minute lifetime.
Session parameters

Practical consequence: a leaked access token expires within 15 minutes at most; the refresh token cannot be exported from the browser; and revoking the jti in Redis ends the session immediately, without waiting for anything to expire.

04Multi-tenant isolation

Mekovault is multi-tenant: several customers share the same infrastructure. Isolation between them is enforced in independent layers, so a defect in one layer does not expose another customer's data.

LayerControl
Data modelEvery row holding customer data carries company_id.
ApplicationEvery query filters by the company carried in the session token. Never by a parameter sent by the client.
DatabasePostgreSQL Row-Level Security as an additional barrier: even if a query forgot the filter, the database returns no rows from another company.
SuperadminPlatform role separate from customer roles. Its actions require code confirmation and verified MFA.
ResellersA reseller sees and operates only on the tenants it manages.
Isolation layers

05Provider credentials and usage audit

To operate on your directory, Mekovault receives credentials with administrative permissions: the JSON of a Google Service Account with domain-wide delegation. They are the most sensitive asset we handle.

  • Stored encrypted in Infisical (self-hosted, on mekovault-vault), in a dedicated project per tenant.
  • Never written to the database, logs or API responses. The database stores only a reference to the secret.
  • Loaded into memory at the moment of calling the provider and discarded when the operation ends.

Immutable record of every use

Every call to Google with a customer's credentials writes a row to the credential_usage_log table.

FieldContent
Tenantcompany_id of the customer owning the credential
ProviderGoogle Workspace
OperationAction executed, for example create_user, suspend_user, add_group_member
ScopesScopes or permissions consumed by that operation
WhoUser who originated the action, or the automated process (worker, timer) that executed it
ReasonReference to the request, ticket or task that justified the call
ResultSuccess or failure, with error code where applicable
LatencyDuration of the provider call in milliseconds
credential_usage_log fields
  • The table has PostgreSQL triggers that reject any UPDATE or DELETE. Not even the Mekovault team can edit or remove an individual row.
  • Each row has a deterministic id derived from the operation. A retry of the same job does not produce a second row, so the log neither inflates nor contradicts itself.
  • A burst of failures against a tenant's credentials raises an alert to the operations team.

Retention

ParameterValue
Minimum24 months
Maximum84 months
ConfigurationPer tenant, within that range
Tenant deletionDeleted with the tenant, or after 24 months, whichever comes first
PurgeWeekly, only of rows outside the configured period. Every purged batch is recorded in the audit trail.
Usage log retention

Export for auditors

The log exports as CSV or JSON. Each file is signed with HMAC-SHA256 and includes the identifier of the key used, so an auditor can verify the file was not altered after it was generated.

06Permissions Mekovault requests

Mekovault asks only for the permissions it needs to manage users, groups and organizational units. It does not request access to mail, files, calendar or any user content.

ScopeWhat it is used for
admin.directory.userCreate, suspend, reactivate and modify user accounts; set an initial password and force its change.
admin.directory.groupCreate groups and lists, and add or remove members during joiner, mover and leaver flows.
admin.directory.orgunitRead and move users between organizational units according to the onboarding or offboarding flow.
Google Workspace (Admin SDK Directory API)

Calls are made with the Service Account impersonating the delegated administrator the customer designates when connecting the domain. That administrator is recorded in every credential_usage_log row.

07Initial passwords and resets

  • When Mekovault creates an account or resets a password, the temporary password is visible to the administrator who executed the action for 15 minutes.
  • After that it is purged from the system. It cannot be recovered: if lost, a new one is generated.
  • Passwords are never written to logs, events or the credential usage log.

08Tenant deletion

A customer can request full deletion of its tenant (right to erasure, GDPR art. 17 and Chilean Law 21.719). The process is designed so credentials disappear before any other data.

  1. A tenant administrator requests deletion. The request is queued as a job.
  2. The tenant becomes inaccessible immediately: its sessions and new sign-ins are rejected.
  3. The job revokes the tenant's secrets and deletes its Infisical project. From this point Mekovault can no longer call the customer's directory.
  4. Only then is the tenant's data deleted in cascade from PostgreSQL: users, requests, tickets, configuration.
  5. The deletion is recorded in the platform audit trail.
  6. Administrators receive a confirmation email detailing what was deleted.

09Addons: modules with limits

Provider connectors and other extensions are packaged as addons. A defective addon must not be able to degrade the whole platform, and the addon registry enforces that rule.

StageControl
DeclarationEach module is described in a manifest with its ports, routes, tables, migrations and health check.
ValidationAutomatic before activation: manifest schema, port, route and table collisions with other modules, applicable migrations and health check response.
ExecutionRuns with memory and CPU limits. A module that overflows is restarted without affecting the others.
SupervisionHealth check every 60 seconds, with the result visible in the operations panel.
Kill switchAny module can be disabled without a deploy: within 15 seconds or less its routes return 503 and the rest of the platform keeps operating.
Addon lifecycle

10Perimeter and browser

ControlEffect
HSTSThe browser connects to the domain only over HTTPS, even if the user types http.
Content-Security-PolicyRestricts the origins from which the portal may load scripts, styles and connections.
X-Content-Type-Options: nosniffPrevents the browser from reinterpreting a file's type.
frame-ancestors 'none'The portal cannot be embedded in an iframe on another site (clickjacking).
Restricted CORSOnly Mekovault origins may call the API from a browser.
No source maps in productionFrontend source code is not published.
No public API documentationThe services' OpenAPI schemas are not exposed in production.
Errors without tracesError responses include no stack traces or internal details.
Portal headers and policies

11Operations and observability

SignalDestination
Structured logs (JSON)Loki, queried from Grafana
MetricsPrometheus
Distributed tracesOpenTelemetry into Tempo
Operational signals
  • A database backup is taken before every deploy.
  • Services are deployed in a controlled way; a failed deploy is rolled back to the previous backup.

Hygiene timers

TaskWhat it does
PII purgeDeletes personal data that has completed its retention period.
Ticket closureCloses resolved tickets with no activity after the configured period.
Secret expirationWarns administrators 30, 7 and 0 days before a provider credential expires.
Usage log purgeWeekly; deletes only rows outside the configured retention and records the batch.
Scheduled tasks

12Security layers summary

LayerControls
PerimeterCloudflare, nginx as the only public process, ufw
NetworkLightsail private network, Tailscale for administration, services on loopback
Identity15-minute RS256 JWT, rotated and revocable HttpOnly refresh, TOTP MFA with rate limit
ApplicationFilter by the token's company_id in every query
DataRow-Level Security in PostgreSQL 16
SecretsSelf-hosted Infisical, one project per tenant, never in DB or logs
AuditImmutable credential_usage_log, export signed with HMAC-SHA256
ModulesValidated manifest, resource limits, supervision every 60 s, kill switch
OperationsPre-deploy backups, hygiene timers, logs, metrics and traces
Controls per layer

13What is in progress

We prefer to say what is missing before a questionnaire asks. These items are being worked on and should not be assumed to be in place until this page moves them to the relevant section.

ItemStatus
ENVIRONMENT=production on every service (today some run with hardened development configuration)In progress
Operational alerts to SlackIn progress
Dedicated PostgreSQL role per addon, so each module reaches only its own tablesIn progress
SOC 2Not planned for now; the framework guides our controls
Technical roadmap

FAQFrequent audit questions

Direct answers to what security teams and auditors usually ask.

Where do my credentials live?
In Infisical, a self-hosted instance on the mekovault-vault machine, inside the AWS Lightsail private network in us-east-1. Each tenant has its own project. The database stores only a reference to the secret, never its value.
Who can see them?
No person sees them in normal operation. Services load them into memory when calling the provider and discard them afterwards. Access to the vault machine requires Tailscale and is restricted to the platform team. Temporary passwords generated by Mekovault are visible to the customer's administrator for 15 minutes and then purged.
What happens if I leave Mekovault?
An administrator requests tenant deletion. Access is cut immediately; then secrets are revoked and the Infisical project is deleted; only after that is the data deleted in cascade from PostgreSQL. The event is recorded in the platform audit trail and administrators receive an email with the details. Sub-processors holding residual data are listed on the sub-processors page.
How do I prove my permissions were not used for something else?
With credential_usage_log: every call to Google with your credentials is recorded with operation, scopes, originator, reason, result and latency. The table accepts neither UPDATE nor DELETE. You can export it as CSV or JSON signed with HMAC-SHA256 and verify the signature with the included key id.
Is a stolen session token useful for anything?
The access token expires in 15 minutes. The refresh token lives only in an HttpOnly cookie, is rotated on every use and can be revoked by jti in Redis. Sensitive operations additionally require verified MFA in that session.
Can a faulty module take down the platform?
It is not designed to be able to. Each addon runs with memory and CPU limits, is supervised every 60 seconds and has a kill switch that disables it within 15 seconds or less without a deploy. The remaining services keep operating.

Request the security package

Includes this document as PDF, the sub-processor list, the signable DPA and answers to standard questionnaires (CAIQ, SIG Lite). We reply within 5 business days.