Hey, I’m Colin! I help PMs and business leaders improve their technical skills through real-world case studies. For more, check out my live courses, Technical Foundations and AI Prototyping.
Creating a prototype is exciting - you've turned your idea into something tangible that you can show to users and stakeholders. But there's a vast difference between a prototype that works on your machine and a production-ready application that can handle real users securely.
As a product manager who's never shipped an app before, the path from prototype to production can seem daunting.
Let's break down the five most critical steps to transform your prototype into a production-ready application:
1. Implement proper authentication and authorization on both client and server
Your prototype might use simple password checks or local storage to manage user sessions, but a production app needs robust authentication on both client and server sides. This double-verification approach is crucial for security.
On the client side, you'll implement UI components for login, registration, and password resets along with session management. But remember that any client-side code can be manipulated by users. This is why server-side authentication validation is essential.
Even if your client code checks for authentication, every API endpoint on your server should independently verify three things:
Is the user authenticated? (Do they have a valid session token?)
Is the token unexpired? (Has their session timed out?)
Is the user authorized for this specific action? (Do they have permission?)
For example, imagine your app has an API endpoint that lets users edit their profile. Your server code should look something like this:
This double-check approach ensures that even if someone bypasses your client-side authentication (which is relatively easy to do), they'll still be blocked at the server level.
2. Secure your secrets and API keys
Your prototype may have API keys, database credentials, and other secrets hardcoded directly in your application code. This approach is a security nightmare for production.
First, let's understand what counts as a "secret":
API keys for third-party services
Database connection strings
OAuth client secrets
JWT signing keys
Encryption keys
Admin credentials
These secrets should never be:
Committed to your Git repository (even private repos)
Hardcoded in your application code
Stored in client-side code that gets sent to browsers
Shared via email or messaging platforms
Instead, implement proper secrets management:
Use environment variables for server-side secrets. These should be set up in your hosting environment (like Netlify, Vercel, or AWS), not in your codebase. You can use a .env file for testing on your own computer and configure it to be ignored by Github with a .gitignore file
For frontend applications, create backend proxy endpoints. Instead of including an API key in your frontend code, create a server endpoint that makes the third-party API call on behalf of your client.
Set up monitoring for API keys. Set a fixed budget or number of requests so you can be notified if traffic exceeds your expectations.
Use the principle of least privilege: each secret should have only the permissions necessary for its function, not admin-level access.
Here's how you might handle a third-party API call correctly:
Proper secrets management is often overlooked but is one of the most critical aspects of production security.
3. Never trust client-side input
In your prototype, you might assume users will provide reasonable, well-formatted input through your UI. In production, you need to assume the opposite.
Any data coming from the client side – whether from forms, API calls, or URL parameters – should be treated as potentially malicious. This includes data from your own UI, as attackers can bypass your interface entirely and send requests directly to your API.
There are two key practices to implement:
Validation ensures data meets your requirements before processing:
Is the email actually an email?
Is the user ID in the correct format?
Are all required fields present?
Do numeric values fall within acceptable ranges?
Sanitization removes potentially dangerous content from input:
Stripping HTML tags from text that will be displayed
Escaping special characters to prevent injection attacks
Normalizing data formats (like phone numbers or dates)
Implement validation and sanitization at both the client and server levels:
SQL injection and cross-site scripting (XSS) attacks often result from failing to properly validate and sanitize input. These vulnerabilities can lead to data breaches or account takeovers, so this step is crucial for production readiness.
4. Set up comprehensive monitoring and alerting
Your prototype probably doesn't need monitoring – when something breaks, you're there to fix it. But a production app needs automated monitoring to identify issues before users report them or, ideally, before users even notice.
Monitoring should catch high priority production issues like crashes and collect data on bugs and poor UX. You can use tools like Sentry to monitor your application performance and PostHog to collect data on user behavior.
Here’s an example of what monitoring looks like with Sentry:
In addition to monitoring, you’ll likely want to set up alerts. These notifications will send you an email when a critical issue has occurred. Set up alerting thresholds carefully – too sensitive and you'll face alert fatigue, too relaxed and you'll miss critical issues. Good starting points include:
Error rates above 1% on critical paths
Response times exceeding 2-3x normal
Any failed health checks
With proper monitoring in place, you can catch issues early, understand your application's behavior patterns, and make data-driven decisions about what to optimize.
5. Secure integrations with third-party services
Your production app will likely integrate with payment processors, email services, analytics tools, and other third-party providers. Each integration is a potential security vulnerability if not implemented correctly.
For payment processing, never handle credit card information directly unless absolutely necessary. Instead, use services like Stripe that provide secure elements to collect sensitive information without it touching your servers.
For email integrations, use established providers with proper authentication and ensure you're following best practices for email delivery and security.
When integrating with APIs, implement these security measures:
Validate webhook sources: If a service sends you data via webhooks, verify the sender using signatures or shared secrets.
Implement rate limiting: Prevent abuse by limiting how frequently your endpoints can be called.
Use minimal permission scopes: When connecting to OAuth services, request only the permissions your application needs, not everything available
Handle API failures gracefully: Third-party services will eventually fail or change. Design your application to degrade gracefully when this happens.
Remember that your application is only as secure as its weakest integration. Review each third-party service carefully and follow security best practices for each.
Putting it all together
Moving from prototype to production requires careful attention to security, reliability, and maintainability.
By implementing proper authentication and authorization on both client and server, securing your secrets and API keys, validating and sanitizing all input, setting up comprehensive monitoring, and securing your third-party integrations, you'll build a solid foundation for your production application.
Great post Colin. I’ve noticed vibe coders getting flack for security issues on Twitter.
I wouldn’t be surprised if businesses pop up to productionize prototypes. Or if the agents automatically help account for a lot of this, eventually.