Trust center: what is in place, and what is not.
Kelynto has no customers and no operating history yet, so this page does not ask for trust. It lists every control with its real status, generated from the same register the engineering team maintains, and leaves the judgement to you.
- 99 Implemented
- 28 Enterprise implementation
- 11 Planned
- 43 Not in place
- Implemented Built into the software, and covered by automated tests or a recorded rehearsal.
- Enterprise implementation Provided by the environment the software is deployed into, as the deployment templates set it up. Not yet running on live infrastructure.
- Planned Written or designed, not yet in effect.
- Not in place Does not exist today. No date is promised.
What does not exist
- No hosted Kelynto service exists today.
- No deployment to a cloud account has been made.
- No SOC 2 report, ISO 27001 certificate, penetration test or service level agreement exists.
Architecture
- Small, fixed set of components Implemented
The product is a web container, an API container, a scheduler job and one PostgreSQL database. Nothing else stores customer data
- Containers run without privileges Implemented
The API and scheduler run as a non-root user with a read-only root filesystem and no-new-privileges in the supplied compose file; the web container is unprivileged nginx. The container rehearsal checks each of these
- Read-only root filesystem on Azure and AWS Not in place
On Azure Container Apps and on AWS Fargate the supplied templates do not set a read-only root filesystem (the platforms do not offer the tmpfs mount the API needs in the same way). The containers still run as a non-root user
- One entry point Implemented
Only the web container is reachable from outside. The API, its metrics endpoint and the database are reachable only inside the deployment's network. The rehearsal checks that no other port is published and that
/metricsis not served outside - Edge controls for the public routes Implemented
The web container limits
/public/v1per client address and for all clients together, answers CORS for listed sites only, refuses writes from other origins, and can switch the public routes off without touching the product API. 35 checks run against a live nginx - Browser security headers Implemented
Every page carries a Content-Security-Policy (
default-src 'self', no framing, no plug-ins), HSTS, nosniff, a no-referrer policy and a permissions policy - Private networking Enterprise implementation
The Azure kit can place the database, Key Vault and registry behind private endpoints and give the application no public address at all (internal ingress)
- Web application firewall Enterprise implementation
The Azure kit can put Azure Front Door with a managed rule set in front of the application, and the origin then refuses requests that did not come through it. The AWS module attaches an AWS WAF web ACL
- Kelynto Managed (hosted service) Planned
A multi-tenant service operated by Kelynto. Designed, and rehearsed on a local machine with stand-in base images. No hosted service is running
- Multi-region or active-active operation Not in place
One region per deployment. A second region is used only for geo-redundant database backups when that option is on
- Cross-browser testing Not in place
Tested in Chromium only. Firefox, Safari, Edge and mobile widths were not tested
- Accessibility assessment Not in place
No assessment against WCAG and no testing with assistive technology has been done
Data handling
- Aggregates only Implemented
The data contract asks for weekly aggregates by store and category. There is no field for shoppers, baskets, payments or employees
- Uploads are parsed as data Implemented
Uploaded files are size-limited, streamed to a temporary file, parsed as tabular data and never executed. A file with too many bad rows is rejected whole
- Logs carry no business data Implemented
Application logs are structured lines with a request id. Request bodies, sales figures, visitor messages and email addresses of leads are not logged. The web container's access log omits query strings and referrers, and the API's own access log is switched off
- Complete list of outbound connections Implemented
Every place the backend opens a network connection is listed with what is sent, the default and the setting that disables it. The list was made by reading the code, not by observing traffic
- No call home Implemented
The software contains no telemetry, licence check or update check addressed to Kelynto
- Outbound lookups can be switched off and checked Implemented
A tool in the API image shows, checks and switches off every outbound signal source and the external language model for a workspace, and writes the change to the audit log. Executed in the external database rehearsal
- Deployment-wide switch that forbids outbound lookups Implemented
DR_OUTBOUND_SIGNALS=falseforbids every weather, alert, event and road-work lookup for every workspace, whatever its settings say: no adapter is built. A workspace admin cannot change it; the settings screen shows the sources as locked andkelynto onboard-checkreports it. Executed in tests with spy adapters; not observed on a network - Website visitor text is redacted Implemented
Card-like numbers, credentials, email addresses and phone numbers are removed from assistant messages before they are stored or sent anywhere. The client address is kept only as a keyed hash that changes every day
- No third-party trackers Implemented
The web app and the public routes load no third-party script and set no analytics cookie. The Content-Security-Policy allows scripts from the application's own origin only
- Data residency commitment Not in place
The region is chosen at deployment. No contractual residency commitment exists for a hosted service, because none is running. In a Customer Environment the customer chooses the region
- Written data classification and handling policy Not in place
Not written yet. It is on the policy list
Authentication
- No passwords stored Implemented
Kelynto holds no password and no password hash. Sign-in is by a customer's identity provider or by an emailed single-use link or code
- Tokens verified against the customer's own provider Implemented
Signature, issuer, audience and expiry are checked against the keys of the provider registered for that tenant. Only asymmetric algorithms are accepted. A token from an unregistered issuer is refused
- The tenant comes from the verified token only Implemented
No request header or unsigned value selects a tenant. An issuer can be registered to one tenant only
- Multi-factor authentication through the customer's provider Implemented
With the customer's own identity provider, MFA and conditional access are enforced there and Kelynto accepts only that provider's tokens for the workspace
- Entra ID app registration script Enterprise implementation
A script creates the two Entra app registrations (API and single-page app), the app roles and the optional claims, and prints the values the deployment needs. Its commands are checked against the installed Azure CLI and its logic was rehearsed against a stand-in; it has not run against a real directory
- Built-in sign-in by emailed link or code Implemented
Single-use, ten-minute links (256-bit token, carried in the URL fragment, redeemed by POST) and six-digit codes bound to the browser that asked, with attempts counted atomically. Off by default
- Server-side sessions that can be revoked Implemented
Built-in sessions are rows in the database. Refresh tokens rotate on every use and reuse ends the session. Access tokens live ten minutes and are checked against the session on every request, so revoking takes effect at once
- Rotating signing keys, encrypted at rest Implemented
The built-in issuer signs with ES256 keys it creates, rotates every 30 days by default and stores encrypted with a key derived from a deployment secret. Production refuses to start without that secret
- Session cookies are confined Implemented
The refresh cookie is HttpOnly, SameSite=Strict, Secure on https and scoped to the sign-in routes. Routes that act on it accept only the application's own origin and JSON bodies
- Second factor for built-in email sign-in Not in place
The built-in sign-in has one factor: control of the mailbox. A workspace can require single sign-on instead
- Resistance of the six-digit code to sustained guessing Implemented
After ten wrong codes for an address within seven days, messages to that address carry the link only (256-bit token), so no further code can be guessed. Wrong attempts against a request that could never succeed do not count, so the lock cannot be held by a third party. Found in review as B-4 and B-5, fixed and re-tested by execution on 3 October 2026
- "Continue with Microsoft or Google" Planned
Written and tested with locally signed tokens. Never verified against the real providers: no app registration exists
- Automated user provisioning (SCIM) Not in place
Users are created from token claims at first sign-in, by invitation or by an admin. There is no SCIM endpoint
- Customer self-service registration of an identity provider Not in place
An operator registers a customer's provider at the command line (
kelynto add-idp). There is no screen for it - Throttling of unauthenticated and failed requests Implemented
Requests without credentials and refused credentials count against the caller's address. Sign-in mail is limited per address and per client and limited at the edge for all clients together. Every message the deployment sends (sign-in, the no-workspace notice, invitations, lead notifications) passes one gate that counts in the database and stops at a ceiling for 24 hours (
DR_SIGNIN_MAIL_DAILY_CAP) - Operator reports need a verified email from a single-directory provider Implemented
The operator reports in the web app are off unless addresses are listed. An operator is accepted only with a token of the shared provider whose email claim is verified by the token itself (
email_verified, orxms_edovfrom one Entra directory). The check cannot be switched off, and the API refuses to start with operators named and a multi-directory Microsoft issuer
Authorisation
- Role-based access inside a workspace Implemented
Four roles with fixed permission sets. Every route that reads or changes workspace data declares the permission it requires
- Roles can be managed in the customer's identity provider Implemented
With the customer's own provider, an app-roles claim is the source of the user's role, and removing the role there removes access on the next request
- A workspace keeps an admin Implemented
The last active admin cannot be demoted or deactivated, and the owner of a self-service workspace can be changed only by the owner
- Invitations bind address and role Implemented
An invitation is for one address and one role, works once, expires, and can be accepted only by a session that proved control of that address
- Invitation mail cannot carry an inviter's text or be sent in bulk Implemented
Fixed subject; the workspace's and the inviter's names appear once, framed as unverified, cleaned to plain characters and withheld when they hold an address or imitate Kelynto. Limits per inviter, per workspace and per recipient are counted in the database, invitations count against the deployment's daily mail ceiling, and under sign-up by approval a workspace invites only once approved
- The allowed email domains are the owner's to change Implemented
Only the workspace owner changes the list. It keeps the owner's and the acting admin's domains, the owner is never closed out by it, and a change that would close out current members names them and needs a confirmation. Changes and refused attempts are audited
- Adding a member requires that person's consent Implemented
In a workspace people sign in to by email, members join only by accepting an invitation: adding an address directly is refused. A membership a person did not create or accept is never opened for them automatically. An admin sees and can end only sessions that have that workspace open, and ending one bars it from that workspace without signing the person out elsewhere. Found in review as B-2, fixed and re-tested by execution on 3 October 2026
- Sample workspace personas are confined to sample data Implemented
A visitor of a sample workspace can look through every persona, including admin, and can change nothing under the administration and organisation routes: no users, settings, invitations or sessions. Found in review as B-1 and B-3, fixed and re-tested by execution on 3 October 2026
- No cross-workspace user Implemented
No application role can read more than one workspace. Operator reports on leads are a separate path that never binds a tenant and is off unless operator addresses are configured
- Operator access to production is logged per person Not in place
Command-line changes are audited under the container's service user, which shows that a change came from the command line, not which person made it. Who opened the shell is in the hosting platform's logs
- Periodic access reviews Not in place
No access review process exists. It is on the readiness list
- No vendor access in a Customer Environment Implemented
The software gives Kelynto no account, key or network path into a customer's deployment. Any access for support is something the customer grants in its own cloud
Tenant isolation
- Tenant filter in the application Implemented
Every ORM query from a tenant-bound session is filtered by tenant; a write for another tenant raises an error
- Forced row-level security on every tenant table Implemented
Each tenant-owned table has
FORCE ROW LEVEL SECURITYwith a policy for reads and writes. A test fails when a tenant-owned table is added without one - Fails closed Implemented
A database transaction bound to no tenant sees zero tenant-owned rows and can insert, change or delete none
- The application is not a database superuser Implemented
The supplied database bootstrap creates an unprivileged role without BYPASSRLS, and refuses to finish if the role could bypass row-level security. Executed against a server whose administrator is not a superuser
- Isolation is checked on the running deployment Implemented
db_check.pyreports whether the role can bypass row-level security, lists tenant tables without a forced policy and counts the rows visible without a tenant (must be zero). Post-deployment validation fails otherwise - Synthetic tenant check Implemented
Validation creates a synthetic tenant, loads invented data, produces a review, checks that another tenant binding cannot see it, deletes it and proves nothing is left
- Account tables have their own policy Implemented
Accounts, sessions, sign-in requests and signing keys are visible only to statements that explicitly enter the accounts scope
- The public site cannot reach tenant data Implemented
The public routes open only sessions that are never bound to a tenant, and the database refuses the public tables to a tenant-bound session. The public write path can never read a lead back
- Separate owner and runtime database roles Enterprise implementation
By default one unprivileged role owns the tables and serves the API, so SQL injected as the application could alter a policy. A two-role layout (owner migrates, runtime role has data privileges only) is documented and exercised by the onboarding rehearsal and a test
- Dedicated single-tenant deployment Enterprise implementation
A customer can have a deployment that serves only its tenant (
DR_TENANCY_MODE=single), in its own cloud account - Separate encryption key per tenant Not in place
All tenants of a multi-tenant deployment share the database's encryption at rest. There is no per-tenant key
- Independent test of tenant isolation Not in place
No third-party penetration test has been performed
Encryption
- TLS for every browser connection Implemented
The application is served over https only; HSTS is sent; plain HTTP is redirected. The single-VM rehearsal checks the redirect and the certificate path locally
- TLS 1.2 or newer at the edge Enterprise implementation
The AWS load balancer uses a TLS 1.2 and 1.3 policy; Azure ingress and Front Door are set to a minimum of TLS 1.2. Post-deployment validation checks that TLS below 1.2 is refused
- Encrypted database connections Implemented
The templates make the database server refuse unencrypted connections. The external-database rehearsal ran the application over TLS 1.3 against a server that accepts TLS only
- Encryption at rest by the cloud service Enterprise implementation
Database storage, backups, secrets and logs are encrypted at rest by the managed services the templates create (Azure Database for PostgreSQL, Key Vault, Log Analytics; RDS with
storage_encrypted, Secrets Manager, CloudWatch Logs) - Customer-managed keys Enterprise implementation
The Azure kit can encrypt the database with a key in the customer's Key Vault (
postgresCmkKeyUri); the AWS module uses the customer's KMS key for the database, secrets, logs and registry whenkms_key_arnis given. Neither has been deployed - Secrets live in the platform's secret store Enterprise implementation
Passwords and keys are generated by the deploy scripts, stored in Key Vault or Secrets Manager and injected as references. Terraform state holds no secret value: the scripts put the values, the module creates only the containers for them
- No secret in the repository or images Implemented
Parameter files hold identifiers only; the images contain no credential. The Azure preflight reports parameter files that still hold placeholder values
- Signing keys encrypted in the database Implemented
Private signing keys are stored encrypted with a key derived from a deployment secret; production refuses to start without one of at least 32 characters
- One-time secrets stored as hashes Implemented
Sign-in links, codes, refresh tokens and invitation tokens are stored only as hashes; the six-digit code's hash is keyed and bound to its request
- Encrypted backups on the single VM Implemented
Database dumps are encrypted with
agebefore upload. The backup and restore drill ran locally with a directory in place of Blob Storage - Key Vault hardening Enterprise implementation
Role-based access, soft delete for 90 days, optional purge protection and optional private endpoint only
- Rotation procedures Enterprise implementation
Step-by-step rotation for every secret is in the runbook. No rotation has been performed on a live deployment
- Rotating the accounts key secret without signing everyone out Implemented
A previous secret is accepted for decrypting stored signing keys only, and a command re-encrypts them under the current secret. Covered by a test; never performed on a live deployment
- Field-level encryption of business data Not in place
Sales, plan and in-stock figures are not encrypted column by column; they rely on the database's encryption at rest and on access control
- TLS between nginx and the API inside one host Not in place
In the compose and VM layouts nginx reaches the API over plain HTTP on the private container network of one machine
Audit logs
- Audit event for every state change Implemented
Uploads, runs, commentary, publishing, labels, settings, user and role changes, and identity provider changes are recorded with actor, action, entity, request id and time
- Settings changes keep before and after Implemented
A settings change records the previous and the new value of each changed field
- Command-line changes are audited Implemented
Operator commands write audit events with the actor
cli:<operating-system user>. This shows the change came from the command line; it does not identify a person - Admins can read the audit log Implemented
Workspace admins read their audit log in the app and at
GET /api/v1/admin/audit, filtered by action - Audit retention Implemented
Audit events are kept for
audit_retention_days(default 2555, minimum 365) and never less than the data retention - Sign-in and session trail Implemented
The built-in sign-in records requests, failures, lockouts, sessions and workspace creation in an account trail kept 730 days
- Platform diagnostics to the customer's log workspace Enterprise implementation
The Azure kit sends container and database diagnostics to a Log Analytics workspace, which can be one the customer already has. The AWS module writes to CloudWatch log groups with a retention the customer sets
- Tamper-evident audit log Not in place
Audit events are ordinary rows. The application's database role could change them. There is no hash chain or write-once store
- Export of audit events to a SIEM Not in place
Audit events can be read through the API. There is no push to a SIEM and no scheduled export
- Record of who read data Not in place
Reads are not audited; only changes are. Request logs record the route and the request id, not the user
Backups
- Automatic backups with point-in-time restore on Azure Enterprise implementation
The Azure kit sets backup retention (parameter, default in the production file) and optional geo-redundant backup on the PostgreSQL server
- Automatic backups on AWS Enterprise implementation
The AWS module sets
backup_retention_period, deletion protection and a final snapshot on the RDS instance. Statically checked only - Encrypted off-machine backups on the single VM Implemented
backup.shdumps, encrypts and uploads;restore.shrestores into a fresh database and checks it. Both ran in the local rehearsal with a directory standing in for Blob Storage - Restore procedure Enterprise implementation
Step-by-step restore for point-in-time, lost region and the VM, and a restore drill that does not touch production
- Restore tested on a real managed database Not in place
The Azure and AWS restore procedures have never been executed: no cloud deployment exists. The VM restore ran locally
- Backup point before an upgrade Enterprise implementation
The upgrade scripts record the time before migrations run, so a point-in-time restore target is known, and refuse to roll the application back across a migration that is not backward compatible without an explicit downgrade
- Committed recovery time and recovery point Not in place
Design targets exist; none is committed in a contract and none has been measured on a cloud deployment
- Customer can export its data Not in place
Reviews and findings export as CSV and documents from the app; the labelled dataset is exportable by the customer. There is no one-step export of everything
Monitoring
- Health and readiness endpoints Implemented
/healthzreports the version;/readyzchecks the database. Container probes and the availability test use them - Application metrics Implemented
Request, error, latency, rate-limit and background-run metrics by route template, plus counters for assistant outcomes, leads, notifications, sign-in requests and verifications, sign-ups, sample workspaces and mail. Not reachable from outside
- Alert rules for a Prometheus scraper Enterprise implementation
34 recording and alerting rules: error budget burn, latency, unhandled exceptions, stuck runs, and the public surface (sign-in outcomes, mail, sign-up, sample workspaces, the assistant, the daily ceilings). Checked with promtool; never loaded into a running Prometheus
- Azure Monitor alerts Enterprise implementation
Availability test, 5xx, restarts, database CPU, storage and liveness, scheduler failures and silence, error logs, and eleven log alerts for the public surface. Compiled and linted; the log queries have not run against a workspace
- CloudWatch alarms Enterprise implementation
Load balancer 5xx, unhealthy targets, database CPU, storage and connections, scheduler failures. Statically checked only
- Daily ceilings on the public surface, with an alert metric Implemented
New conversations, visitor messages, leads, browser events and model calls each have a ceiling per UTC day for the whole deployment, counted in the database. A refusal is counted in
dr_public_daily_cap_total{kind}and logged; the alert rules of the three kits watch it, and an operator command shows the day's counts - Validation after every deployment and upgrade Implemented
One script checks health, version, schema at head, the fail-closed isolation probe, sign-in discovery, the public surface's state, headers and transport, and runs a synthetic tenant that cleans up after itself. Executed locally against the compose stack with an external database (33 checks)
- Counters for sign-in outcomes Implemented
The built-in sign-in counts requests, verifications, sign-ups, sample workspace visits and mail by outcome, with closed label sets and no address in any label. On Azure, where nothing scrapes the counters, the alerts read log events and the web container's access log instead
- On-call rotation Not in place
No rotation exists. Alerts go to one mailbox
- Public status page Not in place
None
- Intrusion detection and security event monitoring Not in place
No dedicated intrusion detection. The web application firewall option and platform logs are what exists
Incident response
- Written incident procedure Implemented
Severity levels, first actions, containment steps for suspected exposure of data, and a communication template
- Containment switches Implemented
A tenant can be deactivated, an identity provider disabled, a person's sessions ended, signing keys rotated and the public surface closed at the edge, each with one command or one setting
- Requests can be traced Implemented
Every response carries a request id that appears in the log line and on audit events written by that request
- Rollback of a bad release Enterprise implementation
Scripts roll the application back to the previous revision and refuse to cross a migration that is not backward compatible unless told to downgrade. Their logic was rehearsed against stand-ins for the cloud command lines, not against a cloud
- Contractual breach notification Planned
No customer contract or data processing agreement exists yet, so no notification period is committed
- Incident exercise Not in place
The procedure has not been rehearsed
- Round-the-clock response Not in place
One person, business hours, best effort
- Vulnerability disclosure channel Planned
A
security.txtthat namessecurity@kelynto.comas the contact is in the site build of 3 October 2026 and is published when that build is uploaded. The policy text is written and is not on the site yet. The mailbox has to be created before the build is published
Subprocessors
- No subprocessor in a Customer Environment Enterprise implementation
The software runs in the customer's account and Kelynto holds none of the customer's data
- Every outside service is listed Implemented
Each service the software can contact, what it receives and how it is switched off is listed, from a reading of every network call in the code
- Optional outside services are off by default Implemented
The event source, road-work feeds, external language model, mail and the website assistant are off until configured. Weather lookups are the exception: on by default
- Subprocessor register for the hosted service Planned
A register exists as a working document with the companies a hosted service would use. No company is engaged, no data processing terms are signed
- Notice of subprocessor changes Not in place
No notice process and no subscription list exist
AI and LLM data flow
- No model is called by default Implemented
The commentary uses the template writer and the assistant is off unless a deployment and, for commentary, the workspace admin switch a provider on
- The commentary model sees aggregated facts only Implemented
The provider receives the week's facts document and nothing else
- Model drafts are checked against the facts Implemented
A draft with a figure or claim that is not in the facts is discarded and the template text is used
- The website assistant cannot reach customer data Implemented
It answers from the knowledge base only and its routes cannot open a tenant session
- Assistant answers pass a claims guard Implemented
In
llmmode an answer that cites an entry it was not given, exceeds the length cap, or states a claim outside the approved entries is replaced by the approved text - Every sentence of a model answer must be backed by a retrieved entry Implemented
In
llmmode a sentence is kept only when one sentence of the retrieved entries holds most of its content words, its numbers and the same negation, and its status label and availability claims agree with the entry's status. Unbacked sentences are removed; a link or address the deployment did not approve, or a request for a password, code, payment or contact detail, discards the answer. Lexical: it compares words, not meaning - The assistant's model mode is optional and off by default Implemented
DR_ASSISTANT_MODEis unset (off) in every deployment file;llmhas to be asked for, needs a provider key and cannot be combined withDR_EXTERNAL_LLM=false. Tested with a fake provider only - Guard outcomes are recorded and counted Implemented
Each model answer's outcome (passed, trimmed, blocked, provider error) is stored with the message, with the reasons and never the discarded text, and counted in
dr_assistant_guard_total{outcome} - Visitor text is redacted before any model call Implemented
Card-like numbers, credentials, email addresses and phone numbers are removed first; the visitor's text is wrapped as data with a per-request marker
- Ceiling on model calls Implemented
A daily ceiling for the whole deployment, counted in the database so that every API replica shares one number and a restart does not reset it. After it the assistant answers from approved text
- Inference inside the customer's cloud Enterprise implementation
With Azure OpenAI as the provider, the deployment can be pointed at the customer's own Azure OpenAI resource. Not exercised against a real resource
- No training on customer data Implemented
No code path sends customer data anywhere for training, and Kelynto holds no customer data
- Reviewed data processing terms with model providers Not in place
No provider is engaged and no terms have been reviewed or signed
- Sample workspace visitors cannot switch a model on Implemented
Settings of a sample workspace, including the external writer and the outbound signal sources, cannot be changed by its visitors. Found in review as B-3, fixed and re-tested by execution on 3 October 2026
- Sample workspaces never reach a model or an outside signal source Implemented
Whatever the settings of a sample workspace say, the commentary writer returns the template writer and the signal refresh asks no source: the check is in the writer and in the adapters, before any provider or adapter is built
- Deployment-level switch that forbids language models Implemented
DR_EXTERNAL_LLM=falsemakes every commentary use the template writer and stops every model call for every workspace, whatever its settings say and whether or not a provider key is present. The settings screen shows the writer as locked. The website assistant cannot run in llm mode with it
Retention and deletion
- Automatic purge by retention period Implemented
The scheduler deletes each workspace's data older than its retention once a day and writes an audit event with the counts
- Verified deletion of a workspace Implemented
One script deletes a tenant and every row it owns in one transaction, verifies that nothing is left and rolls back if something is. Used and checked by the synthetic tenant check
- Retention of website visitor data Implemented
Conversations, events and leads are purged after their periods; one person's lead and conversation can be removed on request
- Housekeeping of sign-in data Implemented
Expired sign-in requests, ended sessions, old account events, retired keys, abandoned empty workspaces and expired sample workspaces are removed by the scheduler pass
- Uninstall removes the deployment Enterprise implementation
Scripts remove a Customer Environment deployment, list what will be deleted first and require the name to be typed. Rehearsed against stand-ins for the cloud command lines
- Deleted data leaves backups Not in place
Backups cannot be edited. Deleted data remains in them until the backup retention (7 to 35 days) has passed
- Self-service deletion of a built-in account Not in place
A person can end sessions; there is no screen to delete the account itself. An operator can disable it
- Written retention policy and data processing agreement Planned
The defaults above are implemented; the policy document and the agreement that commits to them are not written
Customer-hosted deployment
- Azure deployment kit Enterprise implementation
Parameterised templates for subscription, resource group, region, an existing virtual network, private endpoints for PostgreSQL, Key Vault and the registry, private or public ingress, WAF, customer-managed key, managed identity, diagnostics, backups and probes. Compiled, linted and rehearsed against a stand-in; never deployed
- Preflight checks Enterprise implementation
A script checks tools, sign-in, permissions, resource providers, quotas, name availability, the parameter file and the network before anything is created
- Post-deployment validation Implemented
The same validation script runs on every platform: health, version, migrations at head, the fail-closed isolation probe, sign-in discovery and a synthetic tenant that cleans up. Executed locally
- Upgrades with a migration policy Enterprise implementation
Migrations follow an expand and contract policy recorded in a registry; the upgrade scripts refuse an upgrade or rollback that would cross a migration that is not backward compatible without the documented steps
- No long-lived cloud credentials Enterprise implementation
On Azure the containers read secrets and pull images with a managed identity; on AWS with task roles. No access key is stored
- Runs without a connection to Kelynto Implemented
The deployment needs no licence server, no update channel and no Kelynto account. Images are built from the repository in the customer's own registry
- Cloud-neutral path Implemented
Docker Compose with an overlay for an existing PostgreSQL server. Executed locally end to end
- Deployment-level lock on outbound lookups and language models Implemented
Two settings forbid every signal lookup (
DR_OUTBOUND_SIGNALS=false) and every language model call (DR_EXTERNAL_LLM=false) for every workspace, whatever its settings say. The private Azure parameter file and the AWS example set both; the settings screen shows them as locked and the onboarding check reports them. Executed in tests; not observed on a network - AWS deployment kit Enterprise implementation
A Terraform module with the same shape as the Azure kit. Checked statically only; never initialised, planned or applied
- A reference deployment in a real cloud account Not in place
None exists. No template in this repository has been applied to a cloud
- Google Cloud deployment Not in place
A mapping of components to services is written. No templates
- Kubernetes or Helm deployment Not in place
No chart or manifest is supplied
- Marketplace listing or one-click install Not in place
None. The honest path is a script in Cloud Shell or the compiled template in the portal, with manual steps before and after
- Fully disconnected (air-gapped) operation Not in place
Not supported as a tested configuration. The application must reach the customer's identity provider, and building images needs package registries
Vulnerability management
- Pinned dependencies Implemented
The API image installs exactly the versions in a lock file (exact versions; package hashes are not checked); the web build uses the package lock
- Dependency audit, run by hand Implemented
pip-auditon the lock file andnpm auditon runtime packages reported no known vulnerability on 2 October 2026. A point-in-time result - Scheduled dependency and image scanning Planned
A workflow audits dependencies and scans both images on pull requests and weekly. It is linted and has never run: the repository is not hosted
- Automated update proposals Planned
Dependabot is configured for all four ecosystems. Not operating until the repository is hosted
- Software bill of materials Not in place
A bill of materials of the API image was produced by hand once (141 packages). It is not produced or published per release
- Committed time to patch Not in place
No commitment exists. Proposed targets are in the readiness list
- Penetration test Not in place
None performed. A scope is written
- Vulnerability disclosure policy Planned
Drafted. Not published. A
security.txtthat namessecurity@kelynto.comas the contact is in the site build of 3 October 2026; that mailbox has to be created before the build is published - Base images pinned by digest Not in place
Base images are named by tag, so a rebuild can pick up a changed image
- Static checks of infrastructure code Implemented
Bicep is linted, the Terraform module is scanned with checkov (288 checks passed, 13 skipped with a written reason each) and the Dockerfiles with hadolint. Run by hand
Secure development
- Automated tests including isolation Implemented
A backend suite on PostgreSQL covers tenant isolation, sign-in, authorisation, rate limits and retention; a test fails if a tenant table lacks a forced policy
- Production-mode rehearsals Implemented
The images are built from the real Dockerfiles and the stack is exercised end to end locally, with stand-in base images on machines that cannot pull
- Threat model Implemented
A STRIDE threat model per component with mitigations, file references and residual risks
- Security review of new surfaces Implemented
The public API, built-in sign-in, workspaces, invitations and sample workspaces were reviewed on 3 October 2026. Two High and four Medium findings were filed. The two High and three of the Medium ones were fixed by their owner the same day and re-tested by the reviewer by execution. The remaining Medium and three Low findings, on the assistant side, were fixed in release 2.3.0 and tested by their author; the reviewer has not re-tested those
- Linters and static checks Implemented
Ruff, the TypeScript compiler and ESLint for code; shellcheck, hadolint, the Bicep linter, checkov, actionlint and zizmor for deployment code. Run by hand; results recorded
- Claims are tied to evidence Implemented
A script fails when a control marked Implemented names a file that does not exist, or when the published register differs from these pages
- Continuous integration on every change Planned
Workflows for tests, builds, scans and rehearsals are written and pass actionlint and zizmor. They have never run
- Pipeline actions pinned by commit Implemented
Every third-party action in the workflows is pinned to a commit hash
- Passwordless deployment from the pipeline Planned
The deployment workflow uses federated credentials (no stored cloud secret) and an approval gate for production. Written, never run
- Mandatory review by a second person Not in place
There is no second person and no branch protection
- Written secure development policy and training Not in place
Not written
- Signed images and provenance Not in place
Images are not signed and no provenance attestation is produced
- Change management record Not in place
Migrations carry a compatibility record and deployments have a validation record; there is no formal change approval process
Reviewing Kelynto for security or procurement? The security overview lists every known limit and how to get the review pack.
Open the security overview Deployment models Privacy notice for this website