Your AI Writes the Code. Who’s Checking It for Security? Meet ai-Security-Skill A new open-source tool called ai-security-skill provides a local-first security control plane for AI-assisted development, using deterministic code analysis to verify code generated by AI agents. The tool, created by a developer, combines OWASP ASVS V5, OWASP API Security Top 10, OWASP Top 10 for GenAI and LLMs, NIST SSDF, and CIS Controls with TypeScript AST parsing and taint-flow analysis to block builds or commits when critical issues are found. We are living in the golden era of agentic software engineering. Developers are no longer writing code line by line. We are increasingly orchestrating AI agents using tools like Cursor, Windsurf, Antigravity and Claude Code. These agents can build features, debug errors, refactor repositories, and sometimes complete in minutes what would have taken hours. But there is a hidden cost to that speed: Vulnerabilities are being introduced at the same speed. Ask an AI coding assistant to implement a payment gateway and it might produce the entire integration in seconds. But it could also make a dangerous assumption, such as trusting a price supplied by the client. Now comes the more interesting problem. What happens if you ask the same AI agent to check whether the code it just wrote is secure? You get what I call the “marking your own homework” problem. An AI agent can hallucinate, make incorrect assumptions, or convince itself that its implementation is safe. There is no independent verification boundary forcing the generated code to prove that it is secure. That is the problem I wanted to solve. Meet ai-security-skill. As I started using ai coding agents more and more from past 6–7 months the thought of the security always comes to my mind, the Ai agent wrote the application whole code in line minutes now I need to go through important files and check for the security risks that’s when I think of ai-security-skill, it is a local-first security control plane designed to sit directly inside the AI-assisted development loop. Instead of asking an LLM to decide whether its own code is secure, the idea is to give it an independent verification layer based on deterministic code analysis. The Paradigm Shift: Security Needs to Move Closer to Code Generation Traditional Static Application Security Testing SAST tools are extremely useful, but they were designed around a different development workflow. A typical security workflow might look like this: That workflow becomes less effective when an AI agent can generate hundreds of lines of code in seconds. By the time a vulnerability reaches CI, the agent may have already generated several more files that depend on the vulnerable implementation. There is also the problem of noise. Developers can end up with hundreds of security findings and false positives. Eventually, security warnings become something people learn to ignore. AI-assisted development needs a different approach. Security controls should be context-aware . A project using Stripe should have payment-related security checks. A project using PostgreSQL should have database-related controls. A project integrating OpenAI or LangChain should have controls specifically related to AI and agent security. They should also be local-first . Developers should be able to analyze their code without uploading the entire repository to a third-party security platform. And most importantly, the security decision should be deterministic . An LLM can help explain a vulnerability or suggest a fix, but the final security gate should be based on evidence from the code itself. This is the architecture behind ai-security-skill. The system combines two major layers: Knowledge Layer: OWASP ASVS V5, OWASP API Security Top 10, OWASP Top 10 for GenAI and LLMs, NIST SSDF, and CIS Controls. Verification Layer: TypeScript AST parsing, static analysis, and taint-flow analysis. The result is a security pipeline that looks at the project context, determines which controls apply, verifies the actual code, and then makes a policy decision. If everything passes, development continues. If a critical issue is detected, the policy gate can block the build or commit until the issue is fixed or explicitly approved. How ai-security-skill Understands Your Project The first step is context discovery. Instead of blindly running every security rule against every project, ai-security-skill profiles the workspace using discoverProject. It looks at things such as package.json, dependencies, and imports to understand what the application is actually using. For example, it can identify: Application stack: Next.js, Express, Fastify, Svelte, and other frameworks. Database stack: PostgreSQL, MongoDB, Prisma, Drizzle, and related technologies. Authentication: Clerk, NextAuth, OAuth providers, and session-based authentication. Sensitive capabilities: Stripe, PayPal, OpenAI, LangChain, and other integrations. Once the context is established, the system maps the detected stack against its security standards database. Instead of checking hundreds of irrelevant controls, it can focus on the controls that actually apply. For example, detecting Stripe can activate payment amount integrity controls such as CTRL-BL-001. Detecting OpenAI or LangChain can activate AI agent tool validation controls such as CTRL-AI-002. This makes the security analysis more useful because the scanner understands what it is looking at before deciding what to check. Under the Hood: Deterministic Static Analysis At the core of the system is a verification engine built around the TypeScript Compiler API. The code is parsed into Abstract Syntax Trees ASTs , allowing the engine to inspect the actual structure of the application rather than relying only on text matching or an LLM’s interpretation. One of the key capabilities is the Taint Flow Analyzer . Consider a common e-commerce vulnerability. A frontend sends a payment amount to the backend: const { amount } = req.body; js const payment = await stripe.paymentIntents.create { amount, currency: 'usd'} ; At first glance, the code looks perfectly reasonable. But the amount came directly from the client. That means an attacker could potentially manipulate the request and submit a different amount. The important question for a security scanner isn’t simply: “Does this code look suspicious?” It is: “Where did this value come from, and where did it end up?” The TaintAnalyzer tracks exactly that. It identifies untrusted sources such as: req.bodyreq.queryreq.paramsrequest.json It can also identify trusted sources such as database query results. Then it follows how those values propagate through the application. For example: js const price = req.body.price;const amount = price quantity; Even though amount doesn’t directly reference req.body, the analyzer knows that its value originated from an untrusted source. If that value eventually reaches a sensitive sink such as: stripe.paymentIntents.create ... the system can flag the entire flow. This is one of the key differences between deterministic analysis and simply asking an LLM whether code appears secure. The system isn’t guessing. It is following the data. Securing AI Agent Tools There is another security problem that becomes increasingly important as AI agents become capable of taking actions. Modern AI applications expose tools or functions that an LLM can decide to execute. Those tools might include: refund paymentdelete usertransfer moneysend emailupdate account The problem is that these aren’t just functions. They are capabilities . Consider a refund tool: js const refundTool = { name: 'refund payment', description: 'Refunds a transaction using transactionId.', async handler { transactionId } { await db.refunds.create { transactionId } ; }}; The tool performs a sensitive operation, but there is no authorization check. There is no verification that the current user is allowed to refund that transaction. This creates a potentially dangerous attack surface for an AI agent. An attacker could potentially manipulate the agent through prompt injection or another attack and cause it to invoke a powerful tool against an unauthorized resource. The AIAgentAnalyzer is designed to identify this type of issue. It looks for potentially destructive operations such as refund, delete, and transfer, and then examines the implementation for authorization-related signals such as: auth sessionuserIdrole If a sensitive tool appears to be exposed without appropriate authorization logic, the scanner can flag it. As AI systems move from generating text to performing real-world actions, this distinction becomes extremely important. The AI should be allowed to reason about what action to take. But the application should still enforce whether that action is actually allowed. Security Feedback Inside the AI Development Loop One of the features I find particularly interesting about ai-security-skill is its integration with the Model Context Protocol MCP . The security control plane can be exposed as an MCP server and connected directly to AI development environments such as Cursor, Claude Code, or Windsurf. This changes the workflow. the goal becomes: The AI agent can query the security requirements relevant to a feature before implementing it. After generating the code, the local verification engine can scan it. If a vulnerability is detected, the finding can be returned to the agent, allowing it to correct the implementation before the developer even reviews the file. This creates a much tighter feedback loop between code generation and security verification. And importantly, the security engine doesn’t have to trust the AI’s own explanation of whether the code is safe. Architecture Decision Records for Security Exceptions Of course, security scanners aren’t perfect. Sometimes a finding is technically correct but doesn’t represent a real vulnerability in the application’s specific context. For example, a test might execute a SQL query against a hardcoded in-memory SQLite database. A generic scanner could flag that as SQL injection. Instead of adding complicated ignore comments throughout the codebase, ai-security-skill uses Architecture Decision Records ADRs stored inside: .security/decisions/ A decision can document why a particular finding has been intentionally accepted: ADR-001: Exclude SQLi in local tests finding id: SQLI-73716c69rule id: INJ-003expires: 2026-12-31approved: truereviewer: SecurityLeadreason: SQL query is executed against a hardcoded sqlite memory db. The engine can evaluate the decision, check whether it has expired, verify its approval status, and suppress the finding when the exception is valid. The important part is that the reasoning becomes part of the repository. It is version-controlled. It can be reviewed. And it creates a much clearer security trail than simply saying: “Ignore this warning.” Getting Started The goal was to make the setup as simple as possible. Initialize the security layer in an existing project: npx ai-security-skill init Then scan the workspace: npx ai-security-skill scan Check the current security status: npx ai-security-skill status And finally evaluate the project against the security policy: npx ai-security-skill gate The gate can return exit code 0 when the project passes the policy. If critical or high-severity vulnerabilities remain open, it can return exit code 1 and block the build or commit. The entire workflow can run locally. No source code needs to leave the developer’s environment just to perform these checks. Why I Built This AI-assisted development is not going away. If anything, AI agents are going to become increasingly capable of writing, modifying, testing, and eventually deploying software. That means application security needs to evolve with them. We can’t simply bolt security onto the end of the development process and expect that to scale. Security needs to move closer to the point where code is created. But there is also a fundamental trust problem. If an AI agent writes the code and then the same AI agent decides whether that code is secure, we are effectively asking the student to grade their own exam. That doesn’t mean LLMs shouldn’t be involved in security. Quite the opposite. LLMs can be extremely useful for explaining findings, suggesting fixes, understanding application context, and helping developers reason about security decisions. But underneath that intelligence, there should be an independent verification layer that can say: “Show me the evidence.” That is the philosophy behind ai-security-skill. By combining context-aware controls, security standards, deterministic AST analysis, taint-flow detection, AI agent security checks, MCP integration, and local-first execution, the goal is to give developers and AI agents the guardrails they need to move fast without treating security as an afterthought. The project is open source and available on GitHub: https://github.com/Abhishekksoni/ai-security-skill https://github.com/Abhishekksoni/ai-security-skill You can also initialize it directly in an existing project: npx ai-security-skill init I’d love to hear what you think. Have you experienced an AI coding assistant generating a security vulnerability? Do you think AI-generated code should always pass through an independent security verification layer? And if you could add one security check to every AI coding agent, what would it be? Let’s discuss. Your AI Writes the Code. Who’s Checking It for Security? Meet ai-Security-Skill https://pub.towardsai.net/your-ai-writes-the-code-whos-checking-it-for-security-meet-ai-security-skill-e9b9ea641b69 was originally published in Towards AI https://pub.towardsai.net on Medium, where people are continuing the conversation by highlighting and responding to this story.