<?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: Justin</title>
    <description>The latest articles on DEV Community by Justin (@cjustinobi).</description>
    <link>https://dev.to/cjustinobi</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F140226%2F8a9053d4-5e74-4348-a4c7-e2296cbe9fcc.jpg</url>
      <title>DEV Community: Justin</title>
      <link>https://dev.to/cjustinobi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cjustinobi"/>
    <language>en</language>
    <item>
      <title>GridyPig Quiz Clash: Turning Prompts into Multiplayer Games with Hermes Agent</title>
      <dc:creator>Justin</dc:creator>
      <pubDate>Sun, 31 May 2026 19:08:29 +0000</pubDate>
      <link>https://dev.to/cjustinobi/gridypig-quiz-clash-turning-prompts-into-playable-multiplayer-games-with-hermes-agent-3ngc</link>
      <guid>https://dev.to/cjustinobi/gridypig-quiz-clash-turning-prompts-into-playable-multiplayer-games-with-hermes-agent-3ngc</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;GridyPig Quiz Clash&lt;/strong&gt;, an agent-assisted quiz creation and multiplayer game mode inside GridyPig, a multi-tenant real-time game platform.&lt;/p&gt;

&lt;p&gt;The problem I wanted to solve is simple: creating a good quiz for an event, launch party, classroom, community night, or team activity is slow. A creator has to plan the topic, write questions, balance difficulty, avoid repeating old material, validate answer options, and then turn everything into something people can actually play together.&lt;/p&gt;

&lt;p&gt;GridyPig Quiz Clash turns that into a much faster flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A creator describes the quiz they want in plain English.&lt;/li&gt;
&lt;li&gt;Hermes Agent plans the quiz structure and checks the existing reusable quiz bank.&lt;/li&gt;
&lt;li&gt;Hermes avoids duplicate or repeated questions, balances difficulty, and returns generation notes with validated questions.&lt;/li&gt;
&lt;li&gt;GridyPig normalizes the output into a playable quiz set.&lt;/li&gt;
&lt;li&gt;The creator can edit, collapse, import, dictate, save, and launch the quiz as a live multiplayer room.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is not just generated text. It is an agent-assisted path from creator intent to a playable real-time game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Demo link: &lt;a href="https://www.loom.com/share/4092af7b2920444984bcdc73a5363cab" rel="noopener noreferrer"&gt;https://www.loom.com/share/4092af7b2920444984bcdc73a5363cab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recommended demo path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a tenant workspace, for example &lt;code&gt;https://justin.gridypig.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create or sign in as a player/creator.&lt;/li&gt;
&lt;li&gt;Start a new game and choose &lt;strong&gt;Quiz Clash&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;AI quiz builder&lt;/strong&gt; prompt, for example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a fun 8-question quiz about Nigerian tech startups for a launch party. Mix simple and tricky questions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Show the generation button moving through planning, quiz-bank checking, duplicate avoidance, difficulty balancing, and formatting stages.&lt;/li&gt;
&lt;li&gt;Show Hermes generation notes explaining the plan, bank check, duplicate avoidance, and validation checks.&lt;/li&gt;
&lt;li&gt;Save the quiz set and open a live room.&lt;/li&gt;
&lt;li&gt;Join with another player or show the simulation/live room flow.&lt;/li&gt;
&lt;li&gt;Play through a few turns and show the final leaderboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Screenshots/video placeholders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Game landing page&lt;br&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%2Fdwat3dohpjmdzpeo8wqm.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%2Fdwat3dohpjmdzpeo8wqm.png" alt="Game landing page" width="799" height="511"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quiz Builder with Hermes Agent&lt;br&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%2Fcrxxc5rppton0en47ar2.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%2Fcrxxc5rppton0en47ar2.png" alt="Quiz Builder with Hermes Agent" width="800" height="898"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/cjustinobi/greedy-pig" rel="noopener noreferrer"&gt;github.com/cjustinobi/greedy-pig&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hermes Cloud Run adapter: &lt;code&gt;deploy/hermes/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Backend quiz generation service: &lt;code&gt;apps/backend/src/quiz/quiz-ai.service.ts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Quiz APIs and reusable quiz bank: &lt;code&gt;apps/backend/src/quiz/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Frontend quiz setup UI: &lt;code&gt;apps/frontend/src/components/quiz/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Real-time game room: &lt;code&gt;apps/frontend/src/components/game/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js, React, Tailwind CSS, Framer Motion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; NestJS, Prisma, PostgreSQL/Supabase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Realtime:&lt;/strong&gt; Socket.io&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Runtime:&lt;/strong&gt; Hermes Agent behind an OpenAI-compatible Cloud Run adapter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; Google Cloud Run, Docker, Vercel, GitHub Actions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Layer:&lt;/strong&gt; Multi-tenant workspaces, PWA support, referral system, reusable quiz bank, wallet-aware game modes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Used Hermes Agent
&lt;/h2&gt;

&lt;p&gt;Hermes Agent powers the quiz creation layer. I wrapped Hermes in a small Cloud Run service that exposes an OpenAI-compatible &lt;code&gt;/v1/chat/completions&lt;/code&gt; endpoint, so the GridyPig backend can swap AI providers without coupling the game engine to a specific model vendor.&lt;/p&gt;

&lt;p&gt;The flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Creator prompt
-&amp;gt; Hermes plans quiz structure
-&amp;gt; Hermes checks existing quiz bank
-&amp;gt; Hermes avoids duplicate/repeated questions
-&amp;gt; Hermes balances difficulty
-&amp;gt; Hermes returns generation notes + validated questions
-&amp;gt; GridyPig saves playable quiz set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Prompt-to-Playable Structured Output
&lt;/h3&gt;

&lt;p&gt;GridyPig does not need a paragraph of generated text. It needs valid game data.&lt;/p&gt;

&lt;p&gt;Hermes receives the creator's intent and returns a strict schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Short generation plan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"difficultyBalance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"How the quiz difficulty was balanced"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"avoidedDuplicates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bank question or duplicate pattern avoided"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"qualityChecks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Validation checks performed"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"questions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Question text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MULTIPLE_CHOICE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"D"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"correctAnswers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"difficulty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MEDIUM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Why the answer is correct"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend then validates and normalizes the output before it ever reaches gameplay. If a question is malformed, it is rejected instead of silently breaking the room.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Quiz-Bank Awareness
&lt;/h3&gt;

&lt;p&gt;Before calling Hermes, GridyPig samples relevant reusable questions from the tenant and shared quiz bank. That context is passed into the agent as &lt;code&gt;existingBankSample&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hermes is instructed to review that sample, avoid exact duplicates, avoid close paraphrases, and explain what it avoided in &lt;code&gt;avoidedDuplicates&lt;/code&gt;. This makes the quiz pool feel fresher over time instead of repeatedly generating the same obvious questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Generation Notes for Trust
&lt;/h3&gt;

&lt;p&gt;The UI now shows Hermes generation notes after questions are generated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The quiz plan.&lt;/li&gt;
&lt;li&gt;The difficulty-balancing strategy.&lt;/li&gt;
&lt;li&gt;What existing bank questions or duplicate patterns were avoided.&lt;/li&gt;
&lt;li&gt;The validation checks Hermes performed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives the creator confidence that the agent did more than return a blob of questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Agent Adapter Built for Production Constraints
&lt;/h3&gt;

&lt;p&gt;Hermes Agent runs as its own Cloud Run service. During testing I hit real deployment issues: container startup, Cloud Run port binding, long-running agent loops, and noisy CLI output around JSON.&lt;/p&gt;

&lt;p&gt;I solved this by building a dedicated adapter that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Listens on Cloud Run's &lt;code&gt;PORT&lt;/code&gt; correctly.&lt;/li&gt;
&lt;li&gt;Secures requests with a shared secret between the backend and Hermes service.&lt;/li&gt;
&lt;li&gt;Uses ephemeral runtime state so the agent does not hang on Cloud Storage/FUSE SQLite WAL files.&lt;/li&gt;
&lt;li&gt;Bounds generation to a single quiet chat turn for predictable response time.&lt;/li&gt;
&lt;li&gt;Extracts clean quiz JSON even when the CLI returns session noise or markdown wrappers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That adapter made Hermes usable as a real service, not just a local experiment.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Human-in-the-Loop Creation
&lt;/h3&gt;

&lt;p&gt;I intentionally kept the creator in control. Hermes accelerates quiz creation, but the creator can still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edit every generated question.&lt;/li&gt;
&lt;li&gt;Choose predefined or custom categories.&lt;/li&gt;
&lt;li&gt;Pick question type: yes/no or multiple choice.&lt;/li&gt;
&lt;li&gt;Use voice dictation for questions and options.&lt;/li&gt;
&lt;li&gt;Import questions from a template.&lt;/li&gt;
&lt;li&gt;Save questions into a reusable quiz bank.&lt;/li&gt;
&lt;li&gt;Search and reuse existing quiz questions later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because a great quiz is partly AI generation and partly human taste. Hermes gets the creator most of the way there, then GridyPig gives them tools to polish the final game.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It More Than a Quiz Generator
&lt;/h2&gt;

&lt;p&gt;The generated quiz becomes part of a full multiplayer game system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Turn-by-turn Quiz Clash:&lt;/strong&gt; players answer in sequence and the highest score wins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GridyPig streak mode:&lt;/strong&gt; correct answers can keep a player in control, preserving the push-your-luck feel of the original game.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-side validation:&lt;/strong&gt; scoring and turns are enforced by the backend, not trusted to the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inactivity countdowns:&lt;/strong&gt; if a player stalls, the room warns everyone and passes the turn safely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Draw handling:&lt;/strong&gt; tied zero-score quiz games end as draws instead of arbitrarily picking the creator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final standings:&lt;/strong&gt; the game ends with a leaderboard showing how each participant performed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tenant workspaces:&lt;/strong&gt; each business/community can run its own branded games.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable quiz bank:&lt;/strong&gt; creators can build from scratch or reuse questions over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The biggest lesson was that agentic features need product boundaries.&lt;/p&gt;

&lt;p&gt;It is tempting to let an agent do everything, but a real-time game needs deterministic behavior. Hermes is excellent at helping create the content, but the platform still needs strict validation, typed payloads, server-side scoring, and predictable fallback behavior.&lt;/p&gt;

&lt;p&gt;So the winning architecture became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Creator intent
-&amp;gt; Hermes Agent planning and bank-aware generation
-&amp;gt; Structured quiz draft with generation notes
-&amp;gt; Backend validation
-&amp;gt; Human editing
-&amp;gt; Live multiplayer game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That separation keeps the AI useful without letting it destabilize the game loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I want to expand the Hermes layer from quiz generation into a full game-master assistant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suggest better distractor options for weak multiple-choice questions.&lt;/li&gt;
&lt;li&gt;Rebalance difficulty based on historical answer rates.&lt;/li&gt;
&lt;li&gt;Generate themed quiz packs for events, product launches, schools, and community nights.&lt;/li&gt;
&lt;li&gt;Help creators convert reusable quiz-bank content into polished game sessions.&lt;/li&gt;
&lt;li&gt;Create post-game summaries that explain what players struggled with and what they learned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GridyPig started as a dice game. With Hermes Agent, it is becoming a creator-powered game platform where anyone can turn an idea into a live multiplayer experience.&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
      <category>game</category>
    </item>
    <item>
      <title>Building for the bad guys</title>
      <dc:creator>Justin</dc:creator>
      <pubDate>Wed, 20 Mar 2019 08:24:24 +0000</pubDate>
      <link>https://dev.to/cjustinobi/building-for-the-bad-guys-4ek9</link>
      <guid>https://dev.to/cjustinobi/building-for-the-bad-guys-4ek9</guid>
      <description>&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%2Fzg3gkd0x23vk9z1tzifb.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%2Fzg3gkd0x23vk9z1tzifb.png" alt="building for the bad guys" width="799" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Often times, while still in discussion on how to go about a client's project, they always lay emphasis on the security of the app. They would recommend you install the "strongest bad-guys-fighting-software", and I'm always quick to respond that "security is a process." If they fail to do little on their part to ensure the security of the application, irrespective of whatever security plugin that was installed, it could be compromised.&lt;/p&gt;

&lt;p&gt;It would be of no use of installing cool security software and neglect some simple security measure like using a dumb password or even storing passwords&amp;nbsp;in plain text.&lt;/p&gt;

&lt;p&gt;Before I proceed, I would like to define who a bad guy is in the context of this article. A bad guy is simply someone who looks for the slightest means to compromise your application through any loopholes found in the system.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;From the get-go&amp;nbsp;in software development, we plan for the worst and expect&amp;nbsp;it. We assume our attacker is smarter than we&amp;nbsp;are, not leaving any chances for a weak link in the chain.&lt;/p&gt;

&lt;p&gt;So, I will be discussing a few simple ways a developer could avoid being caught in the net of bad hackers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Input field sanitization
&lt;/h2&gt;

&lt;p&gt;This is obvious and most common means of creating an avenue&amp;nbsp;for attack. As a matter of fact, expect the worst wherever there is a form field in your application, a possible outcome is one trying to run JavaScript on your page. That is what’s called an XSS,&amp;nbsp;cross-site scripting.&lt;/p&gt;

&lt;p&gt;So I'm saying basically, treat anyone having access to any of your input fields as a suspect. Anyone with bad intention could put malicious code in those inputs and the rest would be history if the developer of such an app is not security conscious.&lt;/p&gt;

&lt;p&gt;There are tons of great libraries one could leverage on to sanitize HTML, for instance,&amp;nbsp;&lt;a href="https://github.com/cure53/DOMPurify" rel="noopener noreferrer"&gt;https://github.com/cure53/DOMPurify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, all I have mentioned about input sanitization is for the frontend of the development. It is also good to double check it on the server side too because JavaScript could be manipulated on the frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;Authentication is the process of determining whether someone or something is, in fact, who or what it declares itself to be.&lt;/p&gt;

&lt;p&gt;During authentication, credentials provided by the user and are compared to those on file in a database or any other means of storage. If the credentials match then the authenticated user is authorized to use the restricted resources. This leads to my next point; Authorization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;It is granting access to authenticated users. The access could be in different roles (privileges and preferences).&amp;nbsp;The privileges and preferences granted for the authorized account depend on the roles' permissions. The settings defined for all these environment variables are set by an administrator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software updates
&lt;/h2&gt;

&lt;p&gt;One needs to be alert and stay up to date with the latest security patches for the libraries or frameworks they are using.&lt;/p&gt;

&lt;p&gt;With one command, one could update any third party plugin they have installed. This is where the use of package managers shines. With simple commands such as&amp;nbsp;&lt;code&gt;npm&amp;nbsp;update&lt;/code&gt;&amp;nbsp;for Node packages and&amp;nbsp;&lt;code&gt;composer&amp;nbsp;update&lt;/code&gt;&amp;nbsp;for PHP packages&amp;nbsp;etc.&amp;nbsp;one would have any outdated third-party library updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hashing algorithms
&lt;/h2&gt;

&lt;p&gt;Simply put, A&amp;nbsp;hash algorithm&amp;nbsp;is a&amp;nbsp;function&amp;nbsp;that converts a data string into a numeric string output of fixed length. Hackers today have access to powerful inexpensive computing resources that&amp;nbsp;can be used to conduct high-speed password guessing. Salting is the coding technique needed to help defeat such attacks and de-duplication of password hashes since hashing algorithm like MD5 alone is not enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;All the points I have mentioned, are just the basic way one could adhere to in order to&amp;nbsp;avoid stories that touch. There are pretty much points I did not cover. I would be expecting your contributions on any issue not discussed here.&lt;/p&gt;

</description>
      <category>web</category>
      <category>security</category>
      <category>authentication</category>
      <category>authorization</category>
    </item>
  </channel>
</rss>
