Where it runs
- Database and login
- Supabase Postgres in eu-central-1, Frankfurt.
- The API
- A gateway on Fly.io in Frankfurt, in the same region as the database.
- Portals and the studio
- Next.js on Vercel. These serve pages; the data itself is answered by the gateway in Frankfurt.
- Resend, for invitations and login links.
What Kilango stores
Enough to know who is allowed to see what, and nothing that would make Kilango a second copy of your business.
- An organisation
- Name, VAT number, email domain, what kind of counterparty it is, and its place in a group structure if it has one.
- A person
- Display name, email address and language, plus which portals they are a member of and what each membership may reach.
- A link
- The connection between one of your customers and the same customer in your own system, with a note of what matched: a VAT number, a domain, a name.
- A portal
- Your logo, your colour, your domain, which pages exist and which systems feed them.
- A connection
- An encrypted credential that lets Kilango read one of your systems on your behalf.
- Activity
- Who did what, and when.
What Kilango cannot store
There is no table for your projects, your agreements, your invoices, your tickets, your time entries or your employees. Not as a policy that could quietly change, but as an absence in the database.
That absence is checked by a machine. A script reads the schema on every build and fails it if a table or a column is named after a business object. Someone adding a table called Project or a column called invoiceNumber does not get a discussion; they get a red build.
What passes through, and what lingers
When someone opens a page, Kilango asks your system for the answer and renders it. There is no import, no nightly sync and no stored copy of the record. There are three honest exceptions, and they are worth knowing about:
- An answer is held in memory for between thirty seconds and ten minutes so the same page does not ask your system twice. It never reaches disk, and the key includes the exact person asking, so one user's answer can never be served to another.
- If one of your systems sends Kilango an event, the event is stored so a notification can be built from it. That is a message about a change rather than the record itself.
- A notification keeps its own title and one line of text, which came from that event.
Everything else your customer sees on a page was fetched while the page was loading, and is gone when it closes.
How one customer is separated from another
Every table that belongs to a workspace carries the workspace on the row, and the database refuses to return a row that belongs to someone else. The rule is enforced by Postgres rather than by the application remembering to ask correctly, it applies to writes as well as reads, and the account the application connects with is not allowed to turn it off.
That is not a claim about intent. It was tested against the production database: asking for a workspace without saying which one returns nothing, asking with the wrong one returns nothing, and the application account is refused when it tries to create a table or read the migration history. A separate script checks that no new table has been added without the rule.
For someone logged into a portal there is a second gate on top: the request is resolved to a person, an organisation and an active membership on the server, the browser cannot influence any of it, and the membership is re-read on every single request. Revoke someone's access and it stops working immediately rather than when a token expires.
The keys to your systems
You paste a key from your own system, and Kilango encrypts it with AES-256-GCM before it is stored. It is decrypted for the moment a request needs it, it is never written to a log, and it is never returned by any part of the product. Not masked, not partially. Disconnect the system and the encrypted credential is deleted rather than marked inactive.
The connection is made by you, once, for the workspace. Your customers never authenticate to your systems, which is precisely why what a portal can reach is decided inside Kilango.
How people log in
Portals are invite-only and have no sign-up and no password. A person receives a link and a six-digit code in the same email and uses whichever they prefer. Your own team signs in to the studio the same way, and can add a password and an authenticator app.
Looking at a portal as a user
Your team can open a customer's portal and see the exact screen that customer sees. It is the fastest way to answer why something is missing, and it is the most dangerous feature in the product, so it is fenced in on every side.
- It is read only, and that is the first thing checked on every request rather than a permission that could be granted.
- It lasts fifteen minutes and cannot be extended.
- The link that starts it works once and expires after sixty seconds.
- Starting one requires an administrator, and the session cannot begin unless the record of it was written first.
- Starting it, opening it and ending it are all recorded, along with how many times data was read while it was open.
- Live sessions are visible in the studio and can be ended by anyone with the rights to start one.
What is written down
Access changes, portal and page changes, connections, keys, members and impersonation are recorded with who did it, from which address, and against what. For the actions where a missing record would matter, the record is written first: if it cannot be written, the action does not happen.
Who else is involved
- Supabase
- Database and login, in Frankfurt.
- Fly.io
- The API, in Frankfurt.
- Vercel
- Serving the portals and the studio.
- Resend
- Invitations and login emails.
- Twilio
- Phone verification, for your own team's studio accounts only. Portal users never reach it.
- Gandi
- Domain names.
Beyond those, only the systems you connect yourself. There is no analytics, no error-reporting service and no third-party script inside a portal.
What we have not built
Single sign-on with your own identity provider is not available yet, and neither is signing in to a source system with OAuth rather than a key. Both are on the way. We would rather you knew now than found out during an implementation.
We hold no certifications
There is no ISO 27001 certificate, no SOC 2 report and no penetration test report to send you. Getting one is a decision about time and money that has not been made, and until it is, writing a badge on this page would be worth less than the sentence you are reading.
What you can check instead is the architecture. Ask what a table holds, ask what a key can read, ask what happens when you switch it off. Those answers are on this page, and they are the ones a certificate would be summarising.
If your review needs more than this
A security review asks questions this page does not answer, and there are some we would rather answer precisely than approximately. Write to us and you will get a specific answer from someone who has read the code.