DEV Community

SSA
SSA

Posted on

Building DevLog: What Happens When You Tell an AI to Think Like a Security Engineer First

Submission for the Cloud Run AI Challenge — #AccelerateAIwithCloudRun

When I started this challenge, the brief was to build a "Personal Gemini Journal" — an authenticated app where you chat with Gemini and it saves your reflections. Simple enough on paper. The actual point of the challenge, though, wasn't the journal. It was what happens before you write a single line of code: configuring Google AI Studio to behave like a security engineer, not just a code generator.

Here's what I built, why I diverged from the base spec, and what I learned along the way — including the parts that had nothing to do with code.

Phase 1: Teaching AI Studio to threat-model before it builds

The starter directive isn't "write secure code." It's a structured constitution that forces a specific sequence: before any feature gets implemented, AI Studio has to produce a Threat Summary Table mapping risks to countermeasures across five zones — input surfaces, planning/reasoning, tool execution, memory/state, and inter-system communication.

Concretely, this meant every time I asked for a new feature, AI Studio would first lay out a threat/zone/countermeasure breakdown before writing any code. Here's the actual breakdown it produced for DevLog's architecture:

  1. Input Surfaces

Risks: prompt injection/jailbreak attempts in bug descriptions, malformed JSON payloads, client tampering with log identifiers or user IDs
Controls: treat all user input as untrusted plain data, never executable instructions; defensive payload ingestion with schema validation; zero-trust path checks so records only write to /users/{userId}/... matching request.auth.uid

  1. Planning & Reasoning

Risks: hallucinated or non-conforming extraction fields breaking database ingestion; model drift between conversational chat and structured extraction
Controls: strict two-call separation between chat and extraction endpoints; structured output enforcement via Gemini JSON mode (responseSchema); automatic model fallback ladder with schema validation before writing

  1. Tool Execution

Risks: SSRF or arbitrary remote execution if tool calling is improperly scoped; unchecked client-side API key disclosure
Controls: server-side API proxying only, zero exposure of GEMINI_API_KEY to the client bundle; no arbitrary command/code evaluation tools exposed to client endpoints

  1. Memory & State

Risks: cross-user data leakage; insecure default Firestore rules (allow read, write: if true;); orphaned writes or undefined-property crashes
Controls: owner-bound Firestore rules (request.auth.uid == userId); undefined-stripping before every write; Pattern Radar strictly bounded to the authenticated user's own logs, zero cross-user aggregate queries

  1. Inter-System Communication

Risks: Gemini API quota exhaustion or transient failures (429, 503); token/credential leakage in transit
Controls: resilient fallback ladder catching recoverable status codes before surfacing UI alerts; HTTPS/WSS only; Secret Manager for all credentials

That breakdown isn't decoration — it's a contract. If AI Studio proposes code that violates it, that's a signal to push back, not ship it.

Why I didn't build a journal

The base spec is a mood/reflection journal. I build things and break things for a living (well — for a degree, currently), so I asked: what if the thing being journaled wasn't a feeling, but a bug?

That became DevLog — a debugging journal for developers. You talk through a bug with Gemini in free-form chat — actual rubber-ducking, not a guided form — but instead of saving a paragraph of text as the record, the app runs a second, separate extraction call using Gemini's structured JSON output mode to pull out:

json
{
  "title": "PostgreSQL connection pool exhaustion during concurrent batch ingestion",
  "rootCause": "Worker threads opened unpooled client instances per webhook payload",
  "resolution": "Migrated to a lazy-initialized singleton connection manager, max 20 connections",
  "tags": ["postgresql", "connection-pooling", "concurrency", "docker"],
  "difficulty": 4,
  "resolved": true
}
Enter fullscreen mode Exit fullscreen mode

The two-call split matters more than it sounds. One call stays conversational — it's allowed to be messy, exploratory, human. The other call has exactly one job: emit valid, schema-constrained JSON. Mixing those into one call is how you end up regex-parsing "sure, here's your JSON: json..." out of a chat reply, which is fragile and exactly the kind of thing the Secure Coding directive is meant to prevent.

Pattern Radar

Once you have structured tags instead of raw text, a second feature falls out almost for free: aggregate your own tags over time and you get a Pattern Radar — a live view of your most frequent failure modes. After a few weeks of logging, it can tell you "you've hit race-condition bugs 4 times this month" without a single extra Gemini call, because it's just counting data you already extracted correctly.

This is the part I'd point to as the actual "authenticity" differentiator — not because it's flashy, but because it's a real product idea that only exists because of the structured-extraction discipline the security directives pushed me toward in the first place.

The UI pass

Once the app worked, the default AI-generated look was... exactly what you'd expect: dark background, one bright accent everywhere, ALL-CAPS badges, identical bordered cards. I went back to AI Studio with a specific token system instead of "make it look nicer" — named hex values for a greyish-black glass-panel palette, one restrained accent color, sentence-case labels instead of caps. Being specific about the actual design tokens, instead of vibes, is what got a result that didn't look like every other AI Studio demo.

Before:

After:

The challenge accepts a written walkthrough in place of a live URL — and honestly, deciding when a cost/complexity tradeoff isn't worth it for a given deadline is its own kind of engineering judgment. I closed the billing account cleanly afterward and kept building entirely inside AI Studio's own preview environment.

What's next

If I keep working on this past the challenge deadline, the next thing I'd add is a weekly digest — a scheduled job that summarizes a week's worth of logs into "what this pattern suggests you should study next," reusing the same schema-validated extraction pattern rather than opening a new unguarded free-text path.

For now: DevLog does what it set out to do. It's not a mood journal wearing a security badge — it's a genuinely different object (a structured debugging record) built on the same secure skeleton the challenge asked for: Firebase Auth, per-user Firestore isolation, Secret Manager for the Gemini key, and a constitution that made the AI show its threat model before it showed me any code.

Tags: ai, googlecloud, gemini, webdev, accelerateaiwithcloudrun

Top comments (2)

Collapse
 
ghouzlan_dev profile image
Ghouzlan

Love the "think like a security engineer first" framing — most AI coding assistants default to "make it work," not "make it safe." Did you find Gemini's security-first responses ever came at the cost of dev speed, or was the tradeoff worth it?

Collapse
 
ghouzlan_dev profile image
Ghouzlan

The framing of "security engineer first, not just make it work" is really compelling. Curious how you validated that Gemini's outputs were actually more secure and not just more cautious/verbose — did you have a way to measure that?