Product · three surfaces at once9 min read
CPF Seguro
Fraud protection in three places: the app store, a partner's app, and the operator's desk
- +34%
- completion on sign-up inside the partner’s app, after the six-screen flow.
- 3
- surfaces live on one system: the store, a partner’s app, and the operations panel.
- 88
- screen parts with their options, values and defaults declared in one place.
- 22
- flows audited by a program, with readable output.
Product in production. Product Designer at Diletta Solutions, the software company where I work, from November 2021 to today.
00 File
| Product | CPF Seguro · identity protection |
| Where it shows up | its own app in the store · inside a partner's app · operations panel |
| Role | Product Designer · Diletta Solutions |
| Period | November 2021 to today |
| Platform | Flutter, iOS and Android · web panel |
| Tools | Figma, Flutter, Git |
| Scope | 3 surfaces, and I carry all three |
| Partner live | TicTac, a store-offers feed by Directo, a retail technology company |
One line. The same product has to work alone in the app store, embedded in another company's app under their brand, and operated by an internal team. Three audiences with opposite expectations, one system underneath.
01 Summary
Problem. In Brazil, people open accounts and take on debt using someone else's national ID number. The victim finds out from the bill, not from the act. The product sells monitoring and response for that.
What I did. A screen system for all three places, with the partner's brand treated as a planned case rather than an exception. And I moved where a screen is edited: it stopped living in the code and started living in a description that both the design and the program read.
Result. 88 screen pieces with their options declared, 22 flows measured by a program, and the product live in three places at once.
Role. Product Designer at Diletta Solutions, end to end: research, problem definition, UI and handover to engineering.
02 Context
Somebody buying identity protection is afraid. They don't arrive curious, they arrive suspicious, and often they arrive after already being defrauded.
That changes the entire design. In a banking app, the enemy is friction. Here the enemy is doubt: every element that looks like a scam costs a conversion, because the user has already seen scams using exactly that visual language.
And the product is sold two ways. Direct to consumer, in the app store. And embedded in partner companies' apps, with their brand up front.
03 Constraint
The language this product is written in is the Diletta design system, and the partner where the embedded version is live is TicTac, by Directo.
Another company's brand inside our product. In embedded mode, part of the screen belongs to the partner's brand and part to ours. That is a composition rule, and a composition rule does not fit in a color configuration file.
Sensitive personal data, regulated environment. Consent and identity verification are not a place for creativity.
Three surfaces, one team. The operations panel cannot become an orphan project, because it is what holds up support when something goes wrong.
The partner decides when it updates. Their app consumes our system as a versioned dependency. A version that breaks a screen does not get adopted.
04 The problem in numbers
- A fraud is committed every 16 seconds in Brazil. Brazilian Forum on Public Security, 2024.
- The standard scam: open an account, request a card and sign a contract in someone else's name. In many cases the fraudster also uses a photo or video of the victim to pass facial recognition.
- Losses from instant-payment fraud in Brazil could reach US$1.937 billion by 2028, the fastest projected growth in the world.
- By May 2025 there were at least 14 fake websites using real Brazilians' data alongside the visual identity of government pages and credit bureaus.
That last figure is what affects the design most. The scam imitates the interface of the legitimate institution. So the legitimate interface cannot look like the market average, it needs to look verifiable.
05 Decisions
D1 · The partner's brand is a planned case, not an exception
The partner's identity enters through its own color roles and a fixed position in the top bar. It does not enter by overwriting our colors.
Why: overwriting is an invitation to drift, because every new partner asks for an exception. A named role is a contract: the partner fills in what is theirs and cannot reach what isn't.
Measured: the measurements of that composition are written in pixels, in a file, not in the memory of whoever designed it.
Proof in the field: it is live inside TicTac, by Directo. Real client, real brand, and the same product still sits in the store as its own app.
D2 · The screen lives in the description, not in the code file
Each screen is described in a format that both the design and the program read. There is one program that assembles screens, and it reads that description. Editing a screen became editing the description.
Why: with two sources of truth, Figma and the app drift apart within a week, and after that nobody knows which one is right.
What I gave up: the freedom to write a one-off screen however I felt in the moment. In exchange I gained the ability to measure and compare.
D3 · A piece with declared options, not a component with loose parameters
There are 88 screen pieces with their options, possible values and default written in one place. That is what makes it possible to assemble a screen without programming and to check coverage by program.
What I learned by getting it wrong: only the options a piece always renders can receive real data. The ones that appear only under certain conditions receive the data and show nothing, with no error and no warning. I found that by accident, and it became a written rule.
D4 · Flows get measured, not eyeballed
A program audits the product's 22 flows and returns a number. An automated check cannot see that a screen is ugly, but it can see that a screen is missing, and that is the error that most often slips through.
D5 · The credential belongs to the domain, not to the device
Someone registers a passkey in our product and it starts working across the other apps on the same domain, with no password typed again. For a partner's app to join that list, it declares our domain in its own associated domains file.
The order of the flow came out of that decision: first ask whether the person will use more than one device, then offer the passkey and biometrics, and leave the password last.
Why: local biometrics solves unlocking and does not solve identity. It belongs to the device, it is not shared between apps, and it is not what stops someone typing the same password in five places.
The limit, written down, and it matters: it only works inside the same domain. Two different credential managers do not share the passkey, and switching phones only carries it across inside the same ecosystem. A feature with its limit written down is a feature that does not become a broken promise on screen.
D6 · Brand presence in a login flow gets decided with research, not taste
Inside partners' apps our brand was loose: each screen thought through one at a time, with no rule. The risk is direct, and it is about conversion: someone signs into an app with a credential they do not recognize. "Sign in with Google" has the standing to do that. We do not, not yet.
The business position today is to keep the client's brand while there is no scale. Instead of arguing taste against that, I went to find the minimum standard for brand presentation in login flows, to bring data to the table.
And I raised the question nobody had raised: an intermediated login has to be clear to the person signing in, and that is a data protection law obligation, not a finish. The model is the pass-through one, the same as paying with the phone's wallet: the person knows they went through another institution.
The minimum proposal that came out: one line of "authentication by CPF Seguro" under the partner's logo, keeping their colors. It costs one line of text and it resolves transparency and recognition at the same time.
06 Craft
- 88 screen pieces with options, values and defaults declared in one place.
- 22 flows audited by program, with readable output.
- Bank cards drawn one by one, with the usage rule defined in the system and the artwork in the product.
- Browsable documentation published on the web, behind authentication.
- A fast check in 16 seconds, a full one in 2 minutes, and image tests comparing each screen against the approved version.
- During the migration to the new system, I kept 200 name aliases so that no existing call in the app would break.
07 Result
- Three surfaces in one system, with partner mode planned, measured and live.
- The system reaches the app by numbered version, with a record that says what changes in each one.
- What that record exposed when it was created: 176 versions published since the last one the app had adopted, and not one line about what changed.
Two products in the same screen shell. The standalone app has two audiences that are not the same: the people who actually use it, who need what is finished, and the demo for partners and investors, which has to show the whole path. The way out was to treat them as two products with one skeleton, and let the server decide what shows in each environment. Before that the same screen tried to serve both, and the result is what it always is: a feature you can see with no action behind it.
And the process, which was a bigger bottleneck than the screen. Requests arrived one at a time, each one touching several screens, and no definition was written down. Without that, everybody defends their own reading and the discussion becomes whoever talks loudest. I proposed an internal product committee, twice a week, with three obligations: write down each screen's objective, version the home screen, and keep the decision history. The proposal was accepted. It is not design, and it is the thing that changed my work there the most.
Where the number is measured. The operations panel breaks sign-up down by stage and shows the drop from one step to the next, so "where are we losing people" has a screen that answers it. That reading is what backed cutting the embedded flow down to six screens, entered by SMS and never passing through the app store: the most expensive step in any mobile funnel is installation, and the partner mode is the version of the product that does not have that step.
08 What I would do differently
An icon disappeared silently and it took me a while to find it. When the system is installed as a dependency, the image files move, and the program loading them returned empty instead of an error. The screen looked right, just without the icon. It cost ten image tests before anyone noticed.
Silent failure is the worst category of defect in any product. In a product that sells trust, it is the worst of all: the user doesn't see an error, they see a careless institution. Today I would make the image lookup fail loudly.