Skip to content
Expert Guide Series

What security measures should every app developer implement

Security is one of those things that feels abstract until something goes wrong. Then it becomes very concrete, very fast. A data breach costs an organisation an average of $4.44 million globally, according to IBM's 2025 Cost of a Data Breach Report, and once credentials or personal data are exposed, the window to contain it stretches to weeks. What makes that number harder to sit with is that most of the vulnerabilities feeding it were present from the start, baked into decisions made before the first user ever signed in.

Security decisions made late cost far more than decisions made early in the build.

The apps we work on span fitness, social connection, performance coaching, and anonymous messaging. Different audiences, different risk profiles, different data. But the pattern we see across all of them is the same: security decisions made late cost far more than security decisions made early, and security decisions deferred indefinitely tend to surface at the worst possible moment, usually just before launch or just after a complaint that nobody anticipated.

This article covers the security measures every app developer needs to think through, drawn from the work we do with lifestyle brands and the specific products we have built. Some of what follows is structural. Some of it is the kind of detail that only becomes obvious once you have worked through the edge cases yourself.

Threat Modelling Before You Write a Line of Code

Before any code is written, there is a period where the biggest security decisions are effectively free. Changing the authentication model costs nothing on a whiteboard. Changing it after six weeks of development costs six weeks. Threat modelling is the discipline of using that free window properly, mapping out who your users are, what they can do in the app, and where the system could be abused.

The exercise forces useful questions. Who creates content, and who consumes it? Are there admin-level users with elevated privileges? Does the app handle location data, financial transactions, or personally identifiable information? Is there any user-generated content that could be turned against other users? Each answer adds a constraint, and constraints discovered early become design decisions rather than emergencies.

On the anonymous messaging app we worked on, threat modelling surfaced a tension that shaped the entire architecture: the product was anonymous to users, but the moment you allow anonymous messaging without any backend identity, you lose the ability to act on abuse or harassment. That realisation came before we wrote a line of code, which meant the decision to require upfront registration was a deliberate product decision rather than a costly retrofit.

The earlier these conversations happen, the cheaper everything that follows becomes. Teams that skip threat modelling do not skip the threats. They just meet them later, with less room to respond.

Authentication: Getting Identity Right from Day One

Authentication is the first real decision a development team makes about security, and it shapes everything downstream. Get it wrong and you create a point of failure that sits at the front door of the product, visible to every user and every attacker.

We advise clients to look at passive login mechanisms rather than defaulting to either social login or the traditional email-and-password combination. The approach we prefer is entering a phone number or email address and receiving a one-time code. There is no password to remember, no reset flow to build, no credential to intercept, and the simplicity is comparable to social login. The difference is that no user data goes to a third-party platform. Authentication stays internal.

The exception to deferring login is when the nature of the product makes it genuinely unsafe to do so. On the anonymous messaging app we worked on, we put authentication right upfront. The messaging was anonymous to users in the product, but we needed to tie every message back to a specific account on the backend. This was a legal requirement, in place so we could act on reports of abuse or harassment. Product preference said defer the login. Legal and safety requirements overruled it, and correctly so.

The general principle is to match the authentication approach to the actual risk profile of the product, rather than inheriting whatever the framework defaults to.

Start your app project the right way

We deliver the complete blueprint before a line of code is written. User research, psychology-driven design and full technical specifications. You choose who builds it.

See how we work Get started

No commitment

Authorisation and Access Control

Authentication confirms who someone is. Authorisation determines what they can do. The two are different problems, and conflating them is a common source of security gaps.

A user who is authenticated should only be able to read and write the data they are entitled to. On the performance coaching survey app we built, this distinction was the whole architecture. Only authenticated coach accounts could create surveys. Audience members could not browse the list of surveys or read other respondents' answers. Each QR code contained a unique key that granted read access to exactly one survey and write access to exactly one response record. The security model was not just "is this person logged in?" but "is this specific person allowed to touch this specific piece of data right now?"

Access control means asking who can touch which specific piece of data, not just who is logged in.

The practical implication is that access control rules need to be written explicitly, at the data layer, and tested against adversarial scenarios. What happens if a user modifies a request to include another user's ID? What happens if they guess a survey key? Both questions need answers in the security rules before the product goes live.

Write access control rules against a specific adversarial scenario, not just the happy path. Ask what happens when a user substitutes someone else's ID in a request, and make sure the database layer rejects it regardless of what the app layer does.

Securing Your Data Layer Without a Traditional API

A traditional API sits between the client and the database, acting as a controlled intermediary. It validates requests, enforces business logic, and provides a layer where security rules can be applied before data is touched. Building without one is faster for an MVP, but it moves the entire security burden onto the database layer itself.

On the performance coaching survey app, we made a deliberate early decision to skip a traditional API and use Firebase's real-time database directly. For a proof of concept, the build was lean and appropriate. But the trade-off was that we had to scrutinise every Firebase security rule far more carefully than we would have if an API had been acting as gatekeeper. There was no intermediary to catch a badly formed request. If the security rules had a gap, the gap was exposed directly to the client.

What this produced was a model where each survey created a record in Firebase, and audience members accessed their own unique response record via keys embedded in the QR code URL. Real-time response logging worked cleanly. But the security work that would normally be distributed between an API and the database had to be concentrated entirely into the Firebase rules, and those rules had to be exact.

If you build an MVP without a dedicated API layer, document every security assumption that would normally live in the API. Those assumptions do not disappear; they become your database security rules, and they need the same rigour.

Protecting User Location and Personally Identifiable Data

Personal data requires decisions about what you collect, how you store it, and who can see it. Location data is a specific subset with its own risk profile, because precise location information can be used to find someone in the physical world. That distinction matters more for some audiences than others, and the responsible approach is to find out which audience you actually have before deciding how to handle their data.

We worked on a fitness social app originally designed to show users' real-time locations on a map so people could meet up for shared workouts. Research revealed that a high proportion of users were female. That finding changed the product. Showing precise real-time locations to strangers was a genuine safety risk, so we redesigned the feature to introduce randomised location offsets. Users could see a vague area rather than an exact pin. They could then review each other's profiles and have a conversation before choosing to share their precise location.

The product still did what it needed to do, which was give users enough proximity information to judge whether a meetup was realistic. It just did it without exposing anyone's exact whereabouts to people they had not yet chosen to trust. According to NowSecure's mobile app security research, 77% of analysed mobile apps contain personally identifiable information. The question for any product team is whether the data needs to be collected at that level of precision at all.

Anonymous Features Are Not Exempt from Security Design

Anonymous features attract a specific assumption: if users cannot be identified by each other, the security design is simpler. The opposite is often true. Anonymity in the user-facing layer adds complexity in the backend layer, and that complexity has to be managed deliberately.

On the anonymous messaging app we worked on, the core tension was between the anonymity users experienced and the identity the system needed to maintain. Legally, we needed to be able to trace every message back to its sender if a report of abuse or harassment required it. So the app appeared anonymous to users, but every message was tied to an authenticated account on the backend. We also added in-product reporting features so users could escalate concerns about inappropriate or bullying messages directly to the client's admin team. The reporting structure was not an afterthought. It was a necessary part of operating a product where bad behaviour could hide behind anonymity.

The broader lesson is that anonymous features shift safety work from the front of the product to the back. Users cannot self-police through identity because they cannot see who is speaking. So the product has to carry that responsibility itself, through moderation tools, reporting mechanisms, and the legal infrastructure to act on them. Building anonymous features without building that infrastructure is building the problem without building the solution.

QR Codes, Deep Links, and Other Entry Points

Every mechanism that brings a user into the app from outside is an entry point, and every entry point is a potential vector for abuse. QR codes, deep links, referral codes, and shared URLs all fall into this category. They are useful, and they need to be treated as part of the security surface area.

On the performance coaching survey app, QR codes were the primary interaction mechanism. Audience members scanned a code displayed by the presenter, and that code contained the key granting access to that specific survey. We used iOS's built-in libraries to generate the QR codes entirely within the presenter's native app, meaning the codes were never stored externally. The code was only ever live and visible in the venue at the time of the presentation. Once the presenter marked a survey as finished, no further responses could be recorded. The window of vulnerability was the duration of the session, not indefinitely.

We also used a cookie and device fingerprinting to restrict write access to one submission per device per survey. So even if someone shared a QR code link outside the room, a second device could not submit a second response for that survey. The entry point had multiple layers of restriction sitting behind it, not just the key in the URL.

Any URL that grants access to data should be treated as a security boundary. Ask what happens if that URL is copied and shared outside its intended context, then design the permissions accordingly rather than assuming it will only be used as intended.

Security Rules, Indexes, and the Performance Cost of Getting It Wrong

Security rules and database performance are not separate concerns. On document-based databases like Firebase Firestore, the way data is structured and indexed directly affects how efficiently security permission checks can run. Get the structure wrong and the security rules become expensive, and that cost shows up as slow queries and a poor user experience.

We encountered this directly on a real-time messaging product we worked on. The anonymous messaging feature required security rules that let users read messages without exposing the sender's identity. Performance was poor, and we initially assumed the problem was in the application code. After investigation, we found the issue was in the database layer. Adding extra indexes and reworking how messages were stored allowed the security permission checks to run far more efficiently, and the performance problem resolved.

The lesson is that security rules are not free at runtime. They execute against the database structure, and if the structure does not support efficient evaluation of those rules, you pay for it in latency. This means database schema design and security rule design need to happen in conversation with each other, rather than in sequence. Designing the schema first and then writing security rules to fit it often produces structures that make the rules expensive to evaluate.

When Security Rules Become a Performance Problem

The symptoms can look identical to application-level performance issues: slow loads, delayed responses, poor scroll performance in lists. Before assuming the problem is in the code, examine how the database is evaluating its security checks against the current index structure. The fix is often a schema change, not an application change.

In-App Reporting and Safety Mechanisms

Safety mechanisms are part of the product, not a separate compliance layer. Users who encounter harassment, inappropriate content, or behaviour that violates the product's norms need a way to act on that inside the app, without leaving to find an email address or submit a form somewhere else. The easier reporting is to access, the more likely it is to be used.

On the anonymous messaging app, we added in-product reporting features that allowed users to escalate concerns directly to the client's admin team. This was part of a broader set of safety measures we introduced as we worked through the security and safety implications of the product. Anonymous messaging creates specific risks, and reporting is part of how those risks are managed in practice.

The design of reporting features also sends a signal to users about what the product considers acceptable. A reporting flow that is buried three levels deep in settings communicates that reports are tolerated rather than welcomed. A reporting option that surfaces naturally in the context of the content communicates that the product takes safety seriously. Both are accurate signals about the product's actual priorities.

What a Reporting System Needs to Do

At minimum, a reporting mechanism needs to capture what was reported, who reported it, when, and enough context for a moderator to act. The output needs to reach someone with the ability to take action. A report that goes into a queue no one monitors is not a reporting system.

App Store Distribution and Build Access Controls

Access controls during development and distribution are often treated as an administrative concern rather than a security one. In practice, uncontrolled access to App Store Connect and unmanaged build distribution can create real problems as a project approaches launch.

On a social football product we worked on, the client held the App Store Connect Account Holder role since the account was registered in their name. We were given admin access to the majority of the account and set up three internal testing groups: one for our team, one for the client, and one external QA beta test group for the client's testers. The structure was designed to control which builds went to which groups at each stage of the deployment process.

As the project approached launch, the client began bypassing the structure by manually sending uploaded builds to whichever group they chose. Because the account was in their name, they had full access and we had limited ability to prevent this. It caused problems. Builds reached the wrong groups, testing sequences were disrupted, and the controlled release process we had designed was effectively circumvented by the account owner.

The practical lesson is that access structures need to be agreed and documented before the project reaches the pressure of launch. Decisions made informally under time pressure tend to undermine structures that were set up deliberately. Who controls which groups, who approves which builds, and what happens when those boundaries are crossed are questions worth resolving before they become urgent.

The Cost of Retrofitting Security

Retrofitting security into an existing product is significantly more expensive than building it in from the start. The cost is the unpicking of decisions that already assumed a certain security model and the rebuilding of every part of the product that depends on them.

Retrofitting security means unpicking decisions already embedded across the whole product.

On the anonymous messaging app where upfront authentication was a legal requirement, the consequence of that decision spread well beyond the login screen. Because users could not explore the product before registering, we had to front-load all the value communication into the App Store listing rather than inside the product itself. Screenshots, descriptions, and store presence had to communicate everything that would normally unfold through use. That was a significant body of work that existed specifically because of the authentication decision.

If that decision had been made the other way initially and then reversed, all of the onboarding work built around a different assumption would need to be redone. The work compounds. Security decisions made late do not just create new work. They invalidate existing work, and that is where the real cost accumulates.

The same logic applies to data structures, permission models, and encryption choices. A schema designed without considering security rule efficiency will need reworking when performance suffers. Authentication bolted on after the product is live requires every existing session, token, and user flow to be revisited. Building security in at the start is cheaper because it is done once, in the right order, by people who can still change the decisions that matter most.

Conclusion

Security does not start at the point where something goes wrong. It starts at the earliest conversation about what a product does, who uses it, and what data it touches. The decisions made in that window, before code is written and before patterns are established, are the cheapest security decisions you will ever make.

Across the work we do, the most useful security thinking is the kind that happens in context: understanding that an anonymous feature still requires backend identity, that a fitness app serving a predominantly female audience carries different location risks than one that does not, that a QR code is an entry point with the same threat surface as any other URL. These are the specific questions that come up on real products, and they have specific answers that shape the app architecture design.

The recurring pattern is that security and product design are the same conversation, not two separate ones. How authentication works affects onboarding. How access controls are structured affects the database schema. How security rules are written affects performance. None of these are problems you can bolt on later without touching what is already built.

If you are planning a product build and want to work through the security model before the decisions become expensive, let's talk about your app.

Frequently Asked Questions

Why is it so costly to address security issues late in the development process?

Security decisions made early, such as during the design phase, cost very little to implement or change. Once development is underway, retrofitting security measures requires reworking existing code, which can set a project back by weeks and introduce new risks in the process.

What is threat modelling and when should it take place?

Threat modelling is the process of mapping out who your users are, what they can do within the app, and where the system could potentially be abused. It should happen before any code is written, as this is when changes are essentially free and discoveries can inform the design rather than disrupt it.

What authentication method do you recommend for most apps?

A one-time code sent to a phone number or email address is generally the preferred approach, as it removes the need for passwords, reset flows, and third-party data sharing. This keeps authentication simple for the user whilst ensuring that credentials stay internal to the product.

How should developers handle anonymous messaging without enabling abuse?

Even in apps designed to feel anonymous to users, some form of backend identity is needed so that abusive behaviour can be acted upon. Requiring upfront registration is one approach, as it allows moderation and accountability without necessarily exposing a user's identity to other users.

What types of data should trigger extra scrutiny during the security planning phase?

Location data, financial transactions, personally identifiable information, and user-generated content all warrant careful consideration from the outset. Each of these introduces distinct risk profiles and should shape both the technical architecture and the product decisions made around them.

What is the real-world financial risk of poor app security?

According to IBM's 2025 Cost of a Data Breach Report, the average data breach costs an organisation $4.44 million globally. Beyond the financial impact, containing a breach once it occurs can take weeks, and the vulnerabilities responsible are often present from the very beginning of development.

Can security measures be added after an app has already launched?

Technically yes, but doing so is significantly more expensive and disruptive than addressing security from the start. Deferred security decisions tend to surface at the worst possible moments, such as just before launch or following an unexpected complaint, when there is the least room to respond calmly and thoroughly.

Does the type of app affect which security measures are most important?

Yes, different apps carry different risk profiles depending on their audience and the data they handle. A fitness app, a social platform, and an anonymous messaging tool all require distinct approaches, though the underlying discipline of identifying threats early and building around them remains consistent across all of them.