There is a fundamental shift happening in software development right now, and it is not subtle. AI-assisted coding tools like, GitHub Copilot, Claude Code, Cursor, Windsurf, and others have changed the speed at which code gets written. Features that used to take a team a sprint now land in days. Entire modules materialize from a well-crafted prompt. Boilerplate that once consumed hours evaporates in seconds. For developers, this is exhilarating. For security teams, it should be alarming.
The problem is not that AI writes bad code, sometimes it does, sometimes it does not. The problem is volume. Code velocity has increased dramatically, and the human-driven processes that are supposed to catch security issues before they reach production were already struggling to keep pace. Now those processes are being outrun.
The Velocity Gap
Consider the typical security workflow at most organizations. A developer writes code. It goes through code review. Maybe a static analysis tool runs in CI. If the team is mature, there is a periodic penetration test or a threat modeling exercise. These checkpoints assume a certain cadence, a human-paced cadence. They were designed for a world where a senior developer might produce a few hundred lines of meaningful code per day.
AI-assisted development has shattered that assumption. A single developer with a capable AI pair can generate thousands of lines of production code in a day. Not copy-paste boilerplate, real, functional code that interacts with databases, opens network connections, handles authentication flows, and processes user input. Every one of those interactions is a potential attack surface.
Static analysis tools help, but they operate on source code at a point in time. They catch known patterns, SQL injection via string concatenation, hardcoded credentials, obvious path traversals. What they cannot do is tell you what your application actually does at runtime. They cannot tell you that a refactored module now opens a network connection to an unexpected host, or that a new dependency introduced a deserialization path that did not exist last week. And with AI accelerating how quickly code changes, the gap between what static tools analyze and what actually runs in production is widening.
Security teams have never grown at the same rate as development and now development is 10x’ing their code velocity. Security teams can’t hire their way out of a 10x increase in code velocity.
What AI-Generated Code Actually Looks Like in Practice
AI coding assistants are genuinely impressive tools. I use them myself, Claude Code is deeply integrated into my own workflow. But using these tools daily also gives you a front-row seat to the kinds of issues that slip through.
AI models are trained on vast amounts of open-source code, and open-source code is a mixed bag. The model might generate a perfectly correct implementation of an HTTP client but default to disabling certificate verification because that pattern appeared frequently in training data — often in examples, tutorials, and test code where convenience trumped security. It might produce a file-handling routine that works correctly but follows user-supplied paths without sanitization. It might wire up a database connection using a pattern that is vulnerable to injection in edge cases the model never encountered.
Lack of focus on non-functional requirements are not hypothetical concerns. They’re patterns and exactly the kind of issues that are easy to miss in code review — especially when the reviewer is looking at a large pull request that was produced in a fraction of the time it would have taken to write manually. The sheer volume creates review fatigue, “code blindness”, and review fatigue creates blind spots.
The Limits of Shift-Left
The security industry has spent the last decade evangelizing “shift left”, the idea that security should be integrated earlier in the development lifecycle. And that is a good idea. Static analysis in CI, dependency scanning, secret detection in pre-commit hooks, all valuable. But shift-left has a blind spot: it assumes that catching issues in source code is sufficient. It is not.
Source code tells you what the developer intended. Runtime behavior tells you what actually happens. These are not the same thing, and the gap between them grows larger in complex applications with deep dependency trees, dynamic classloading, reflection, and runtime configuration. A Java application with two hundred transitive dependencies is not going to reveal all of its runtime behavior through static analysis alone. It cannot.
This is the gap that runtime security monitoring is designed to fill. And it is the gap that is becoming critical as AI accelerates the pace at which new code — and new runtime behavior — enters production.
Runtime Visibility: Watching What Code Actually Does
This is where JVMXRay fits into the picture. JVMXRay is a Java agent that attaches to any JVM application via the standard -javaagent flag — no source code changes required. It uses ByteBuddy bytecode injection to observe how the application interacts with protected resources at runtime: file I/O, network connections, SQL queries, cryptographic operations, process execution, HTTP requests, authentication events, reflection, serialization, and more. Nineteen modular sensors cover the major categories of security-relevant behavior.
What makes this approach different from traditional logging is structure and scope. JVMXRay does not produce unstructured log lines that require regex parsing and hope. Every event is emitted as a structured, machine-readable Logback message with consistent key-value pairs. Events are automatically correlated across sensors via trace IDs and scope chains, so you can reconstruct the sequence of operations that led to a particular action — not just the action itself.
This is the kind of visibility that lets you answer questions like: Did the new release introduce any unexpected network connections? Is the application accessing files outside its expected working directory? Are SQL queries being constructed dynamically with user input? Is the application using weak or deprecated cryptographic algorithms? These are runtime questions, and they require runtime answers.
Expanding the Security Frontier
The metaphor I keep coming back to is “frontier security.” In any system, there is a boundary between what you can see and what you cannot. On one side of that boundary, you have visibility, logs, metrics, alerts, dashboards. On the other side, code analysis. Beyond that, there is darkness. Threats that live in the dark are the ones that get you.
For most Java applications today, the security frontier stops at the edges, the WAF, the API gateway, maybe some application-level logging that was added ad hoc over the years. What happens inside the JVM between the request arriving and the response leaving is largely invisible. You might know that a request came in and a response went out, but you do not know what the application did in between. What files did it touch? What connections did it open? What classes did it load? What did it serialize or deserialize?
JVMXRay pushes that frontier inward. It gives you visibility into the interior behavior of the application itself — the part that static analysis cannot reach and perimeter tools cannot see. And because it operates as a standard Java agent, it works with any JVM application: Spring Boot services, legacy monoliths, servlet containers, microservices, batch processors. If it runs on the JVM, JVMXRay can observe it.
There is another blind spot worth mentioning here, and it is one that teams frequently overlook: not all the code running in your environment is code you wrote or code you can even read. Commercial off-the-shelf software ships as compiled binaries. You do not get to review it. Even when source code is technically available, Tomcat, Logback, Spring Framework, and the rest of the open-source stack your application depends on, most teams do not review it. They may not have the expertise, the time, or the mandate to audit third-party code at that depth. It is treated as trusted by default, because the alternative is impractical.
But trusted is not the same as safe. A JVMXRay agent attached during integration testing or in a staging environment can surface what all of that code, yours and everyone else’s, actually does at runtime. Think of it as a behavioral audit that does not require source access. If a commercial library opens an unexpected network connection, writes to a temp directory it should not touch, or exercises a cryptographic path you did not anticipate, you will see it in the event stream. It is not a replacement for code review where code review is possible, but it provides a level of assurance for the code that nobody is reviewing, which in most organizations, is the majority of what actually runs.
Meeting the AI Challenge
Here is the connection back to AI-accelerated development. When code velocity increases by an order of magnitude, you need security mechanisms that can keep pace without requiring a proportional increase in human effort. JVMXRay is designed to operate at that scale.
Attach the agent to your application. Deploy it. Every security-relevant action is captured and structured automatically, no manual instrumentation, no code annotations, no developer cooperation required. Feed those structured events into your existing SIEM or log aggregation platform: Splunk, ELK, Datadog, Kafka, whatever your team already uses. Build alerts and dashboards on top of consistent, machine-readable data. Now you have continuous runtime visibility that scales with your deployment, not with your headcount.
When a developer uses an AI assistant to generate a new service endpoint in an afternoon, and that endpoint goes through CI and code review and lands in staging by end of day — JVMXRay is already watching. If that endpoint opens an unexpected database connection, loads a class via reflection that was not in the original design, or makes an outbound HTTP call to a domain that has never appeared before, you will see it. Not because someone remembered to add logging. Not because a static analysis rule happened to match. Because the agent is observing the actual runtime behavior of the application, automatically.
The Road Ahead
AI is not going to slow down. The tools are getting better, the adoption is accelerating, and the volume of AI-assisted code entering production is only going to increase. This is not a problem to be solved, it’s a reality to be adapted to. The developers who use these tools effectively will build faster. The organizations that thrive will be the ones whose security practices evolve to match.
It means investing in runtime visibility as a first-class security capability, alongside your static analysis capabilities, not an afterthought. It means accepting that you cannot review every line of code a human-AI team produces, and your open source software supply chain, yet building systems that provide confidence in what your applications are actually doing.
JVMXRay proof of concept is one piece of that puzzle. It is not the entire answer — no single tool is. But it fills a critical gap: the space between what your code says and what your application does. In a world where code is being written faster than ever before, that gap is where the risk lives. And closing it is no longer optional.
If you want to see JVMXRay in action, the GitHub repository has everything you need to get started. Clone it, build it, attach it to a test application, and see what your application is actually doing. You might be surprised.