<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rizzy65</title>
    <description>The latest articles on DEV Community by Rizzy65 (@rizzy_cc89484f09).</description>
    <link>https://dev.to/rizzy_cc89484f09</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3534884%2F4fdbcba4-10e0-4b85-8ffb-1d010d0ca347.jpg</url>
      <title>DEV Community: Rizzy65</title>
      <link>https://dev.to/rizzy_cc89484f09</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rizzy_cc89484f09"/>
    <language>en</language>
    <item>
      <title>Dev Log #2 - From Scaffolding to First Telemetry</title>
      <dc:creator>Rizzy65</dc:creator>
      <pubDate>Fri, 24 Oct 2025 06:46:35 +0000</pubDate>
      <link>https://dev.to/rizzy_cc89484f09/dev-log-2-form-scaffolding-to-first-telemetry-48ae</link>
      <guid>https://dev.to/rizzy_cc89484f09/dev-log-2-form-scaffolding-to-first-telemetry-48ae</guid>
      <description>&lt;p&gt;If Dev Log #1 was about laying bricks, this one is about seeing the first lights turn on (and as a dev, it feels good.) Mirage/Apate went from “neatly stacked parts” to “a system that actually notices and remembers what touches it.” It’s still early to call it alive, but it’s real—and that’s a good feeling.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Shipped: working backbone (API + SSH/HTTP emulators), data persistence (DB + Redis), and a CI that has my back.&lt;/li&gt;
&lt;li&gt;First telemetry: login attempts, HTTP pokes, and early session traces.&lt;/li&gt;
&lt;li&gt;Lesson: real signals beat perfect plans—ship the simplest believable thing, then iterate.&lt;/li&gt;
&lt;li&gt;Next: smoothing the emulators’ “personality,” better dashboards, and a tiny predictive prototype&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What changed since Log #1
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The API has a heartbeat. You can browse the docs locally (Swagger UI) and poke at endpoints without spelunking through code.&lt;/li&gt;
&lt;li&gt;SSH and HTTP emulators are alive. They respond, they log, and they do it in a way that feels “real enough” to keep curious hands around a bit longer.&lt;/li&gt;
&lt;li&gt;Data is sticky. Sessions, attempts, and a basic threat score now land in a database, with Redis helping keep things snappy.&lt;/li&gt;
&lt;li&gt;The boring-but-critical stuff is there: Docker to run it all, iptables to keep it contained, and CI to tell me when I broke something.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In short: it’s not just a blueprint—it’s a house with lights, doors, and a guestbook, that forgets everything after a while, &lt;em&gt;But I am working on it&lt;/em&gt;.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  A tiny demo (60 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start it up (Docker makes this painless).&lt;/li&gt;
&lt;li&gt;Visit the API docs in your browser.&lt;/li&gt;
&lt;li&gt;Trigger a simple request to see it flow through.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# bring services up (example)&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# check API is alive&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8000/health

&lt;span class="c"&gt;# explore the interactive docs&lt;/span&gt;
&lt;span class="c"&gt;# open http://localhost:8000/docs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you should notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Health endpoint is up&lt;/li&gt;
&lt;li&gt;Docs are browsable&lt;/li&gt;
&lt;li&gt;New events show up as you interact with the emulators&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Design notes, without the PhD
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start with “believable enough.” If the emulators feel roughly like a real box, attackers will stay long enough to teach us something.&lt;/li&gt;
&lt;li&gt;Keep the core tight. FastAPI for orchestration, Rust for fast/precise network handling, Redis/SQL for state. Fewer moving parts = fewer surprises.&lt;/li&gt;
&lt;li&gt;Observe first, outsmart later. The “cognitive” layers will come, but the best training data is real behavior—so step one is to listen well.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What didn’t work (and what I changed)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I tried to over-script the SSH conversation early on. It felt brittle. I pared it back to a realistic baseline, then made room to layer nuance later.&lt;/li&gt;
&lt;li&gt;I flirted with Postgres too soon. Switched to a simpler default (SQLite) for local flow, kept the door open for Postgres when it earns its keep.&lt;/li&gt;
&lt;li&gt;I wanted dashboards on day one. Reality: get clean events first; pretty plots after. The data is now solid, so charts are next.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make the emulators more “human”: better prompts, more natural delays, fewer tells.&lt;/li&gt;
&lt;li&gt;Dashboards that make sense at a glance (Grafana first, then iterate).&lt;/li&gt;
&lt;li&gt;A tiny predictive experiment off to the side: can a simple model guess the next command on a toy dataset? Not production—just curiosity with a yardstick.&lt;/li&gt;
&lt;li&gt;Safer defaults and more guardrails as I harden the container boundaries.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  If you’ve read this far
&lt;/h2&gt;

&lt;p&gt;Thanks. Building Mirage/Apate feels a bit like putting together a stage play: sets, lights, and a story that’s convincing enough for the audience to stay. The first claps (telemetry) are in. Now it’s about deepening the act—slowly, carefully, and with a smile. &lt;em&gt;Hopefully, my drive for this lives on to finish the play.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/Rizzy1857/Apate" rel="noopener noreferrer"&gt;Apate (GitHub)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs (local when running): &lt;a href="http://localhost:8000/docs" rel="noopener noreferrer"&gt;Swagger UI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Previous: &lt;a href="https://dev.to/hrisheekesh_pv_cc89484f09/dev-log-1-mirage-apate-field-notes-from-the-first-brick-3c91"&gt;Dev Log #1 — Field notes from the first brick&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>programming</category>
      <category>ai</category>
      <category>development</category>
    </item>
    <item>
      <title>Dev Log #1 — Mirage / Apate: Field Notes from the First Brick</title>
      <dc:creator>Rizzy65</dc:creator>
      <pubDate>Sun, 28 Sep 2025 13:57:09 +0000</pubDate>
      <link>https://dev.to/rizzy_cc89484f09/dev-log-1-mirage-apate-field-notes-from-the-first-brick-3c91</link>
      <guid>https://dev.to/rizzy_cc89484f09/dev-log-1-mirage-apate-field-notes-from-the-first-brick-3c91</guid>
      <description>&lt;p&gt;We spun up the first Mirage container. It looked cocky in &lt;code&gt;docker ps&lt;/code&gt;, even served a clean 200. We thought: &lt;em&gt;hell yeah, prod vibes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then someone hit the DB. Brick wall. Container “running,” but the service was a wax statue. Lesson #1: process alive ≠ system alive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Day 0 — Naive boot
&lt;/h2&gt;

&lt;p&gt;What we thought:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple ASGI app, SQLite, Alembic migrations.&lt;/li&gt;
&lt;li&gt;Compose to glue it, nothing fancy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DB init blocked startup. Import-time schema creation froze everything.&lt;/li&gt;
&lt;li&gt;Logs filled with &lt;code&gt;OperationalError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Container alive, endpoints dead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Patch:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feai0t4v3ilg77uo66604.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feai0t4v3ilg77uo66604.png" alt="A Python code snippet defining an application startup event handler using an @app.on_event(" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lazy DB init, async startup, short timeouts.&lt;/li&gt;
&lt;li&gt;Service now boots instantly, even if DB ghosts us.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; we learned fast—DB fallback isn’t free. Our in-memory SQLite behaves &lt;em&gt;nothing&lt;/em&gt; like Postgres. Attackers probing concurrency, types, or isolation will sniff the toy. For now, it’s fine for dev loops, but TODO: move to WAL-backed SQLite with jitter, or a lightweight Postgres sidecar, so Mirage doesn’t leak “cheap decoy.”&lt;/p&gt;




&lt;h2&gt;
  
  
  Persistence discipline
&lt;/h2&gt;

&lt;p&gt;What we tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQLite file for dev, Postgres later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File collisions on container restart.&lt;/li&gt;
&lt;li&gt;Migrations stomping each other, state corruption.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Patch:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foi9fsvs244nipm719qe2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foi9fsvs244nipm719qe2.png" alt="Python code for an asynchronous function named init_database. The code attempts to connect to a database using SQLAlchemy's create_async_engine. If the connection or table creation fails, it catches the exception, logs a warning, and enables an in-memory fallback mode. The code also includes a conditional check for a _USE_ALEMBIC flag to decide whether to create database tables." width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Async SQLAlchemy for proper async flow.&lt;/li&gt;
&lt;li&gt;Alembic migrations gated behind &lt;code&gt;APATE_USE_ALEMBIC&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rudimentary file lock to avoid racey migrations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; file lock is a band-aid. Real fix: advisory locks in Postgres (later), or one-shot init jobs in Compose/K8s. Note for future self: never trust humans to “just remember the flag.”&lt;/p&gt;




&lt;h2&gt;
  
  
  Surface tightening
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg064s4okt0g3q93zk6y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg064s4okt0g3q93zk6y2.png" alt="A Python code snippet showing two asynchronous API endpoints for a health check in the 'Mirage Honeypot' application. The first endpoint at / provides a basic status, while the second endpoint at /status gives a detailed JSON breakdown of components like SSH, HTTP, and an AI engine, including their ports and individual statuses." width="800" height="860"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Favicon probes spammed 404 logs → return 204.&lt;/li&gt;
&lt;li&gt;Added env-driven CORS.&lt;/li&gt;
&lt;li&gt;Sensitive routes gated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TODOs we spotted mid-flight:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handle HEAD/OPTIONS consistently.&lt;/li&gt;
&lt;li&gt;Add robots.txt + a boring 1x1 favicon instead of “nothing.”&lt;/li&gt;
&lt;li&gt;Rate limiting + small randomized latency on select routes, so we don’t look “too perfect.”&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Observability, but noisy on purpose
&lt;/h2&gt;

&lt;p&gt;Before: dead silent when things broke.&lt;/p&gt;

&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/metrics&lt;/code&gt; with Prometheus counters (requests, latencies, DB fallback count).&lt;/li&gt;
&lt;li&gt;Webhook alerts with dedup/backoff.&lt;/li&gt;
&lt;li&gt;Metrics for alert failures themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Self-own:&lt;/strong&gt; right now, degraded mode leaks via the public health probe (it literally says “fallback engaged”). That’s a fingerprint. Fix queued: external health always boringly “OK,” internal metrics carry the truth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing loop
&lt;/h2&gt;

&lt;p&gt;What we had: slow, flaky tests with external deps.&lt;br&gt;
What we have: 53 async tests run in ~0.5s in-process with ASGI.&lt;br&gt;
What we still need: property-based tests for degraded paths (DB flaps mid-request, migration lock races).&lt;/p&gt;




&lt;h2&gt;
  
  
  Early wins
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deterministic startup.&lt;/li&gt;
&lt;li&gt;Sub-second tests.&lt;/li&gt;
&lt;li&gt;Real metrics instead of vibes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TODOs and risks we logged for later
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DB realism:&lt;/strong&gt; WAL-backed SQLite + jitter, or Postgres-lite sidecar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health signals:&lt;/strong&gt; split readiness/liveness; external = opaque, internal = honest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migrations:&lt;/strong&gt; kill the file lock, replace with advisory locks or init jobs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surface polish:&lt;/strong&gt; HEAD/OPTIONS, robots.txt, rate limiting, fake latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability polish:&lt;/strong&gt; structured logs with request IDs, Prometheus histograms + exemplars, maybe traces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI gates:&lt;/strong&gt; ruff, mypy, bandit, pip-audit, safety; pinned deps; multi-arch builds; distroless images.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Config:&lt;/strong&gt; doc all env vars (DB URL, fallback toggles, alembic flag, origins, alerts).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;Honeypots don’t have to be perfect, but they do have to be believable. Right now Mirage boots, degrades, and talks enough to fool a casual scan. But any serious fingerprint will still smell the shortcuts.&lt;/p&gt;

&lt;p&gt;The plan: brick it less, make failure louder, make the illusion tighter.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Prod or bait? If they have to stop and wonder, Mirage did its job.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can check the progress of my work in Github &lt;a href="https://github.com/Rizzy1857/Apate" rel="noopener noreferrer"&gt;Apate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or just myself at &lt;a href="https://github.com/Rizzy1857" rel="noopener noreferrer"&gt;Rizzy1857&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any and every comment or contribution to make it better will be appreciated.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
