Skip to content
·10 min read

Security Logging for Vibe-Coded Apps and What You Must Track

The security events your app should log, how to store them safely, and what to look for when something goes wrong

Share

Security logging is the difference between knowing you got breached last Tuesday and finding out three months later when your users' data shows up on a forum. With 92% of developers using AI tools daily and 45% of AI-generated code containing vulnerabilities, your vibe-coded app needs logging to catch attacks before they become disasters.

Most AI-built applications ship with zero security logging. The AI generates functional code, you deploy it, and when something goes wrong you have nothing to look at. No record of who tried to log in and failed. No trace of which admin changed permissions. No evidence of whether the breach happened yesterday or six weeks ago.

This tutorial covers exactly what to log, what never to log, how to structure and store your logs, and how to set up alerts that tell you something useful.

The Events You Must Log

Not every action in your application matters from a security perspective. You do not need to log every page view or button click. You need to log the events that indicate something is wrong or that would be critical evidence during an incident investigation.

Failed login attempts are the single most important security event to capture. A user failing their password once is normal. The same IP address failing fifty times in ten minutes is a brute-force attack. Without logging, those fifty failures look exactly the same as zero failures. You see nothing.

Successful logins from new locations or devices matter because they indicate account takeover. If a user has logged in from Chicago for six months and suddenly logs in from a different country, that deserves attention.

Permission and role changes are critical. When someone upgrades a user to admin or modifies access controls, you need a record. If an attacker compromises an account, one of their first moves is to escalate privileges. Without logs, you will not know it happened.

Data exports and bulk reads flag potential data exfiltration. A user downloading their own profile is normal. A single account pulling every record in a table is a breach in progress.

Admin actions of every kind need logging. Configuration changes, user deletions, feature flag toggles, database migrations. If an admin account is compromised, the audit trail is how you understand the scope of the damage.

API errors and 4xx/5xx responses reveal attack patterns. A spike in 401 Unauthorized responses means someone is probing your endpoints. A surge in 400 Bad Request errors means someone is fuzzing your inputs looking for injection points.

Key Takeaway

Focus your security logging on five categories: authentication events (failed and successful logins), authorization changes (permission and role updates), data access patterns (exports and bulk reads), admin actions (any configuration or user management), and API anomalies (error spikes and unusual response patterns). These five categories cover the evidence you need for 90% of security incidents.

What You Must Never Log

This is where most developers make a critical mistake, and where AI-generated logging code is especially dangerous. There are things that should never appear in your logs under any circumstances.

Passwords and password hashes must never be logged. Not in plain text, not as hashes, not as "masked" values. If your AI tool generates a login handler that logs the request body, it is logging passwords. Every login attempt. Sitting in plain text in your log storage.

API keys, tokens, and session identifiers should never appear in logs. If an attacker gains access to your logs, they gain access to every active session. Log that a token was used, not the token itself. Log the last four characters if you need to identify which key was involved.

Personally identifiable information like email addresses, phone numbers, and credit card numbers should be excluded or masked. Log a user ID, not their email. Log that a payment was processed, not the card number.

The reason this matters is practical. Logs are often stored with weaker access controls than your primary database. They get shipped to third-party services and shared with team members during debugging. Every piece of sensitive data in your logs has a wider attack surface than the original.

{
  "timestamp": "2026-04-05T14:32:01.847Z",
  "event": "login_failed",
  "userId": null,
  "attemptedUsername": "admin",
  "ip": "203.0.113.42",
  "userAgent": "Mozilla/5.0...",
  "reason": "invalid_credentials",
  "failCount": 12
}

Notice what is in this log entry and what is not. There is a timestamp, the event type, the IP address, and the failure count. There is no password. There is no session token. There is enough information to investigate an attack without creating a new vulnerability.

Common Mistake

AI coding tools frequently generate logging middleware that captures the entire request body, including passwords, tokens, and personal data. Before you ship, search your codebase for any logging that records req.body, request.body, or similar full request dumps. Replace them with selective logging that captures only the fields you need for security investigation.

Structured Logging in JSON Format

If your application logs unstructured text strings, you are making incident response dramatically harder than it needs to be. Unstructured logs look like this:

[2026-04-05 14:32:01] ERROR: Login failed for user admin from 203.0.113.42

That is human-readable, but it is nearly impossible to search, filter, or alert on programmatically. You cannot easily count how many failed logins came from a specific IP in the last hour. You cannot build a dashboard. You cannot set up automated alerts.

Structured JSON logging solves this. Every log entry is a JSON object with consistent fields. Your logging service can index every field, and you can query them like a database.

{
  "timestamp": "2026-04-05T14:32:01.847Z",
  "level": "warn",
  "event": "auth.login_failed",
  "ip": "203.0.113.42",
  "attemptedUsername": "admin",
  "reason": "invalid_credentials",
  "metadata": {
    "failCountLast10Min": 12,
    "geoCountry": "XX",
    "userAgentHash": "a1b2c3d4"
  }
}

In Node.js, use pino or winston with JSON transport. In Python, use structlog. These libraries handle JSON formatting, log levels, and timestamp generation so you do not need to build it yourself. Ask your AI tool to set up structured logging with pino, and verify the output format matches what your log storage service expects.

EXPLAINER DIAGRAM: A comparison showing two approaches to security logging side by side. Left side labeled UNSTRUCTURED LOGS shows three plain text log lines in a monospace font, with a red X and text HARD TO SEARCH, HARD TO ALERT. Right side labeled STRUCTURED JSON LOGS shows the same three events as formatted JSON objects with consistent fields like timestamp, event, ip, and userId, with a green checkmark and text SEARCHABLE, FILTERABLE, ALERTABLE. An arrow points from left to right with text UPGRADE YOUR LOGGING.
Structured JSON logs turn security events into searchable, alertable data instead of text you have to read line by line.

Where to Store Your Logs

Here is a rule that matters more than almost anything else in this article: do not store security logs on the same server that runs your application. If an attacker compromises your server, the first thing they do is delete the logs. If the logs are on the same machine, your evidence disappears with one command.

Ship your logs to an external service. For vibe-coded applications, these are the practical options:

Axiom offers a generous free tier with 500 GB of ingest per month. It handles structured JSON natively and has a solid query language. For most indie projects, you will never hit the free tier limit.

Better Stack (formerly Logtail) has a free tier with 1 GB per day and built-in alerting. The setup is straightforward, usually a single environment variable and an HTTP transport in your logging library.

Sentry is primarily an error tracking tool, but it captures enough context around errors to serve as a lightweight security log. If you are already using Sentry for error monitoring, you can extend it to cover security events without adding another service.

For any of these services, the integration pattern is the same. You configure your logging library to send JSON over HTTPS to the service's ingest endpoint. The service indexes your logs and makes them searchable. Setup takes fifteen minutes.

Running a Vibe-Coded App in Production?

Security logging is one piece of the ship-safely puzzle. Get the full picture.

Read more

Setting Up Alerts That Actually Matter

Logs without alerts are an archive. You will not sit and watch log streams all day. You need automated alerts that tell you when something abnormal is happening, and those alerts need to be specific enough that you do not ignore them.

Set up alerts for these patterns:

More than 10 failed login attempts from a single IP in 5 minutes. This is a brute-force attack. The threshold depends on your application, but 10 in 5 minutes is a reasonable starting point for most apps.

Any permission escalation to admin. This should trigger an alert every time, no threshold. Admin creation should be rare enough that every instance deserves human review.

More than 100 API errors from a single IP in 10 minutes. This indicates automated probing. Someone is running a scanner against your endpoints looking for vulnerabilities.

Data export or bulk read exceeding normal patterns. If your average user reads 5 records per session and an account suddenly reads 10,000, that is exfiltration.

Every alerting service lets you define rules based on field values and counts over time windows. Start with these four alerts. You can refine the thresholds as you learn what normal traffic looks like for your specific application.

EXPLAINER DIAGRAM: A vertical flow chart with four boxes connected by arrows pointing downward. Top box labeled YOUR APP in gray has an arrow pointing to second box labeled LOG SERVICE (Axiom, Better Stack, Sentry) in teal. The second box has two arrows pointing down: one to a box labeled ALERT RULES with four sub-items listed as bullet points (brute force detection, permission escalation, API error spikes, bulk data access), and another arrow to a box labeled DASHBOARD showing a simple bar chart icon. The ALERT RULES box has an arrow pointing to a final box labeled NOTIFICATION (Email, Slack, PagerDuty) in coral. Below the diagram, text reads LOGS FLOW OUT, ALERTS FLOW BACK.
The complete security logging pipeline: your app ships structured logs to an external service, alert rules monitor for suspicious patterns, and notifications reach you through the channels you already check.

Log Retention and Your Deletion Policy

How long you keep logs matters for both security and compliance. Too short and you lose evidence of slow-moving attacks. Too long and you are storing data you are liable for under privacy regulations.

A practical retention policy for most vibe-coded applications is 90 days for detailed logs and 1 year for aggregated security metrics. The 90-day window covers the average breach detection time. The 1-year aggregated metrics give you trend data without retaining individual request details.

If your application handles data subject to GDPR, HIPAA, or similar regulations, check the specific retention requirements. Some regulations mandate minimum retention periods. Others cap how long you can keep data. The free tiers of most logging services handle retention automatically, purging data after the configured window.

What This Means For You

Security logging is not optional for production applications, especially not applications where nearly half the code may contain vulnerabilities. The setup is not complicated. Pick a structured logging library, configure five event categories, ship logs to an external service, and set up four alerts. The entire process takes an afternoon.

The payoff is that when something goes wrong, and in this threat landscape something eventually will, you have evidence. You know when it happened, what was accessed, and how they got in. You can respond in hours instead of discovering the breach months later. That is the difference between a security incident and a security catastrophe.

Building With AI Tools?

Security logging is your early warning system. Set it up before you need it.

Start here
PJ
Pranay Joshi

20+ years building products at scale. VP of Product & Engineering, startup founder, and AI coach. Helping dreamers turn ideas into reality with vibe coding.

The Tuesday Shipping Report

Every Tuesday, one focused email:

  • - The tool or technique that's actually working right now
  • - A real problem from the community (and how to solve it)
  • - What changed this week in the vibe coding landscape

Read by 1,000+ founders, developers, and creators building with AI. Free forever. No spam.