Skip to main content
Status: Accepted.

Context

A customer reaches their account three ways: the Telegram login widget in a browser, the Mini App’s signed initData inside Telegram, and a generic OIDC provider an operator has configured. A fourth, the sign-in link, is a fallback requested from the bot rather than from a web form. A password is absent. Operators have one — internal/adminauth hashes it, rate-limits it, locks the account out, pairs it with TOTP or a passkey, and notifies on every credential change — so the absence on the customer side is not a gap in what the codebase can do. It was a choice, and until this record it was written down nowhere, which made it read as an oversight to anybody who compared the two route lists. Three facts about this installation shape the choice. There is no e-mail transport. No SMTP client, no provider adapter, no configuration for either. The operator password-reset flow issues a token only from a command run on the server, which prints it for out-of-band delivery — defensible for a handful of operators who can reach each other, and not a customer-facing mechanism. Answering “do you know this address?” is the thing the panel refuses to do. It is why the sign-in link starts in a chat the customer has already authenticated to, and why a contact address already registered elsewhere is refused as “not available here” and nothing more. A password form has to take an identifier and then either accept it or reject it, and every version of that answer tells a stranger whether somebody is a customer here. A customer already arrives holding a stronger credential. Telegram and an OIDC provider both authenticate the person before Omniflow sees them, and both can carry a second factor that Omniflow does not have to implement, store, or recover.

Decision

The customer panel does not offer a password, and customer_identities never stores a secret. A customer authenticates through a party that already authenticated them — Telegram or an OIDC provider — or through a link the bot delivers into a chat they already control. The absence is a property of the schema, not of the UI. There is no password column, no reset-token table, and no hashing parameters on the customer side. A future screen cannot quietly reintroduce one; adding it means a migration and superseding this record. Adding a customer password requires an e-mail channel first. A password without a reset path locks people out permanently, and a reset path needs a delivery channel that reaches a customer who by definition cannot sign in. Telegram is not that channel: the customers who would most want a password are the ones who do not have Telegram.

Consequences

An installation must enable at least one of Telegram or OIDC, or nobody can sign in on the web. This is the real cost and it is not small. An operator selling into a market where Telegram is blocked and no consumer identity provider is acceptable has no configuration that works, and no amount of configuration produces one. GET /v1/account/auth/methods returns an empty list and the sign-in screen says so plainly rather than rendering a form that cannot succeed. A customer database leak carries no credential to crack. There is nothing to hash badly, nothing to reuse across sites, and nothing an offline attack can work on. This is the security property the decision buys, and it is worth more than the convenience it costs. Whole categories of work do not exist. No breach-list check, no password strength meter on the customer side, no lockout tuning, no reset-token expiry policy, no credential-change notification path, no “your password was changed” support script. Password reset is the largest single support category in consumer products, and this installation has none of it. The account recovery story is somebody else’s. A customer who loses access to their Telegram account or their identity provider recovers it there, not here. The panel’s handoff for identity conflicts and irreversible actions points at support, and support’s answer is to help them prove control of the upstream account rather than to issue a new credential.

Revisit when

  • E-mail transport exists and is a supported, configured channel rather than a documented absence. Until then a password is a credential with no recovery path, which is worse than no password.
  • A concrete installation demonstrates customers it cannot sign in — not a preference for passwords, but a market where neither Telegram nor any acceptable OIDC provider is available. That is the observable condition, and it is the one that would justify paying for the whole stack above.
Note that a verified e-mail address is already stored as a contact channel and is already used for consent and delivery preferences. Its existence is not the condition; a transport that can send to it is.
  • Customer web panel — the three methods, and what each refuses.
  • OIDC providers — configuring an identity provider for customers and for operators.
  • Security — the operator credential stack this record deliberately does not mirror.
  • Privacy — what an installation stores about a customer, and what it does not.