Building a Mental Model for Kubernetes Security Research

Read Time

26 mins

Published

Jul 8, 2026

Share

TL;DR: How Codex helped me turn Kubernetes security research into a usable mental model and research framework

During security engagements involving Kubernetes (sometimes abbreviated to k8s), one of the recurring challenges I keep running into is how difficult it is to understand and analyze the security posture of a cluster once it exists in production. Part of the problem is that the cluster does not stay still. It changes, as does the environment around it, and the amount of relevant identity, access, configuration, and application-behavior information grows quickly. That is why the questions that end up mattering most usually come from production-shaped scenarios, where fluidity and scale make it harder to reason about what is happening and what it means.

In practice, the core problem is rarely understanding one Kubernetes or cloud feature in isolation. It is understanding how the different components interact, how they influence each other, and how those relationships come together to create an attack surface. That is the point where a cluster stops looking like a list of features and starts looking like a living environment whose behavior has to be understood as a whole.

This is also where Codex, OpenAI’s LLM-based coding assistant, became useful to me as a research companion. It helped me take a problem like that, combine it with what I already knew about Kubernetes, Azure Kubernetes Service (AKS), Azure, and infrastructure, and reason through it until it started to take a more usable shape. The end result was not only a cleaner way to explain the problem, but a framework I could use to create and study scenarios deliberately. That made it possible to use focused environments to explore specific questions, deepen my understanding of Kubernetes and AKS, and build toward the larger goal of being able to explore production environments where the real challenge is the volume and fluidity of the information in front of you.

What ended up making the biggest difference for me was approaching the problem from a first-principles perspective. That gave me a way to reason about the different components that participate in an AKS deployment before getting lost in provider settings or implementation details. It also gave me a more stable foundation for understanding how a Kubernetes cluster fits into a larger cloud environment, where it stops being an isolated piece of technology, and starts becoming part of a wider system of identity, control, and integration.

Kubernetes Principles and AKS Integration

By itself, Kubernetes is a platform that enables applications to run, heal, scale, and connect. It is also a control system that decides how those applications are deployed, managed, and constrained. Once that same platform is placed inside Azure, it can be extended through different integration points and configuration choices that change how identities reach and influence the cluster, and how applications or workloads behave when they interact with other systems inside or outside the cluster.

A cluster has two sides that are easy to collapse together if we are not careful. One is the application side, where workloads live and interact. The other is the management side, where operators and automation interact with the cluster itself. Keeping those two views separate makes it easier to understand why identity, authorization, and admission matter so much in the first place.

At the workload level, this is the side most people recognize first: pods, controllers, services, and the surrounding object model. This is where applications become reachable, configurable, and operational. It is also where later questions about workload identity and service interaction begin to appear.

This distinction matters because the cluster is not only running applications, but deciding who can manage those applications; how requests are handled; and what rules shape the environment those workloads live in. This is the side of the cluster where control starts to come into view.

Kubernetes Control Path

Control in Kubernetes begins with the request path into the cluster. A request, in this case, is any attempt to ask the cluster to do something through the API: create an object, modify an existing one, retrieve information, or trigger some other action. That request reaches the API server, which acts as the main control surface of the cluster.

This is where management requests are evaluated. The API server decides whether the identity behind the request is trusted, whether the requested action is allowed, and whether the request should still be constrained by policy or object-level controls. Authentication, authorization, and admission only make sense because there is a control path being enforced, and the API server is at the center of that path.

That is also the point where authentication, authorization, and admission start to matter more clearly. They are not abstract Kubernetes terms floating on their own, but rather the mechanisms that shape who can reach this control path; what they can do once they reach it; and what kinds of workloads the cluster is willing to accept.

Authentication

Authentication is the first question in that path: who are you from the cluster’s perspective? At a high level, this is about what credential is being presented and what trust source the cluster accepts. Kubernetes is not limited to a single built-in identity path. It can trust different credential types and, when configured to do so, different identity issuers.

Authorization

Authorization asks the next question: now that an identity has been accepted, what is it allowed to do? This is where the cluster evaluates access to resources and actions rather than only identity validity. Kubernetes RBAC is the familiar example here, but the broader idea is simply that accepted identity and permitted action are not the same thing.

Admission

Admission is the next layer in the path. Even if an identity is valid and authorized, the object being submitted may still be rejected or changed. This is where policy-oriented and object-shaping logic can participate. It becomes especially important once the focus shifts from who can manage the cluster to what kinds of workloads the cluster is willing to accept.

These ideas explain the control side of Kubernetes, but they are only one half of the picture. Once a workload has been accepted, the next question is what that workload becomes inside the cluster, how it interacts with other services, and what identity paths it may need to do that. That is the other side of the system and once both sides are visible, it becomes easier to understand what Azure and Entra are actually extending when Kubernetes is deployed as AKS.

Kubernetes Workload Behavior

Once a workload has been accepted, it moves out of that request path and into the runtime side of the cluster, where Kubernetes orchestration takes over. This is the point where the scheduler, controllers, node pools, and surrounding compute layer make it possible for the application to actually run. This is where pods live, and where they are turned into actual containers that execute the code and bring the application to life.

Workloads participate in relationships with other systems. A workload may call internal cluster services, interact with the Kubernetes API, reach external cloud services, or expose its own service surface to something else. Identity questions emerge from those relationships rather than from the mere fact that a pod exists.

That matters because any workload that reaches a protected service needs some way to identify itself. That may involve service accounts, tokens, certificates, or external federation paths. The key idea is simpler than the mechanism: once access control is involved, the workload needs an identity path. What changes from one scenario to another is the specific credential pattern and trust relationship that path depends on.

Kubernetes Extension Points in AKS

Once that workload-side baseline is clear, the next step is to see what changes when Kubernetes is deployed as AKS. This is where Azure and Entra begin to participate in the same control and workload paths described above. Some of those integration points affect how people retrieve credentials and reach the cluster. Others affect how workloads obtain identities and connect to external services. This is also where the comparison among native service accounts, federated identity paths, and static credentials starts to matter more, because each one changes not only the trust relationship but also how credentials are delivered into the workload and what kind of exposure or attack surface comes with that delivery path.

One of the clearest AKS integration points appears in authentication. You can configure Kubernetes to trust an external identity system rather than relying only on more local credential paths. In AKS, Entra can become that identity platform. That means a token issued by Entra can be presented to the cluster, and the cluster will accept it because the trust relationship has been configured to extend beyond Kubernetes itself. This is one of the first places where the picture starts to change, because authentication is no longer only a cluster-internal concern.

The next extension point appears after identity has been accepted. In a more Kubernetes-native path, the main question becomes what that identity can do inside the cluster through RBAC and related controls. In AKS, that picture can widen when Azure-side authorization begins to participate in who can retrieve cluster credentials, who can influence the cluster as a resource, or how accepted identities are mapped into later permissions. The important point is not only that permissions exist, but that the place where they are decided may no longer live entirely inside Kubernetes.

Admission is another place where the extension surface becomes visible. Once identities and permissions are in place, the cluster still has to decide what kinds of workloads it is willing to accept. In practice, that can mean labels, annotations, identity hooks, or other deployment requirements that a workload has to satisfy in order to participate in a given scenario. This is where the shape of the workload itself starts to reflect the trust and control model around it.

These extension points do not stop at identity. Once Kubernetes is deployed as AKS, the surrounding surface expands into networking, computing, storage, secret handling, cluster architecture, and the way control-plane state is protected or exposed. That is part of what makes AKS powerful, but it is also part of what makes it harder to reason about directly. The problem is no longer only understanding Kubernetes by itself but, rather, understanding how it and the surrounding cloud platform begin to shape each other.

All of these extensions ultimately come back to the workload. They shape how applications receive identity, how they authenticate, what permissions they receive, what deployment patterns they need to follow, and what runtime conditions they depend on. This is why the same application can behave differently depending on how the cluster is configured around it. That is also the point where the problem stops feeling like a list of disconnected features and starts looking like something that needs a reusable model in order to make sense of it.

The Mental Model

This is the point where the mental model starts to become explicit. Once the cluster stops feeling like a collection of isolated features and starts looking like a system of interacting decisions, it becomes harder to reason about directly without some way to organize those decisions by meaning. What emerged for me was a mental model that created different categories based on meaning (in essence, a taxonomy).

What made that useful is that the taxonomy gave me a way to look at a cluster through a set of connected lenses rather than through a flat list of settings. Those lenses connect back to the same first principles we talked about earlier: control, identity, workload behavior, runtime conditions, and the surrounding mechanisms that shape how the cluster actually works. In that form, the taxonomy categorizes features and becomes a way to see the cluster in terms of what the different decisions mean. The easiest way to see what that means is to walk through those lenses one by one.

Cluster Control

Cluster control focuses on the cluster as an Azure-managed resource and on the identities that can influence, manage, or constrain it as such. On the design side, this includes decisions such as administrative access paths, trusted identity systems, management boundaries, and the ways control over the cluster resource is delegated or exposed. When reading a real environment back, it helps identify which users, groups, managed identities, or service principals can exert control over the cluster and how that influence is expressed from Azure or Kubernetes.

Credential Retrieval

Credential retrieval focuses on how identities obtain the material needed to reach or act through the cluster. At the specification level, this includes kubeconfig retrieval paths, local accounts, token or secret delivery paths, and other external credential dependencies. In a live environment, it helps answer who can obtain usable access material and what that access makes possible next.

Authentication

Authentication focuses on the conditions under which an identity is trusted by the cluster or a dependent service. Here, the important decisions include trusted issuers, token validation paths, service-account trust, and external identity-provider integration. From an analysis perspective, it helps identify who can authenticate and through which trust relationship.

Authorization

Authorization focuses on what an accepted identity is allowed to do once it is trusted. That includes Kubernetes RBAC, Azure RBAC integration points, workload permissions, and delegated access models. When the cluster is being assessed, this lens helps reveal what actions are possible under a given identity context and where privilege or influence begins to accumulate.

Admission

Admission focuses on what may be introduced into the cluster even after authentication and authorization succeed. At this layer, the important pieces are policy engines, workload constraints, object validation or mutation, and deployment guardrails. On the analysis side, it helps clarify what kinds of workloads or configurations the cluster is willing to accept and how that shapes both abuse opportunities and defensive boundaries.

Workload Management

Workload management focuses on how workloads are represented, deployed, and allowed to behave once running. This includes workload identity patterns, service-account use, application deployment shapes, namespace or controller choices, and the way application artifacts are delivered into the cluster, such as how container images are sourced from a registry and what assumptions that introduces into the deployment path. In a collected environment, it helps show how cluster decisions affect application behavior, workload identity paths, and service interactions.

Data and Storage

Data and storage focuses on how persistent data, secrets, and storage-backed resources are represented and protected in the cluster. The relevant decisions here include secret handling, encryption choices, persistent volumes, storage classes, mounted data paths, and related protection mechanisms such as etcd or secret encryption. When viewed analytically, it helps reveal where sensitive material resides, how workloads gain access to it, and what operational or security implications follow from the way data is stored and exposed.

Computing

Computing focuses on the node, runtime, and execution architecture that shape how workloads actually run inside the cluster.

At this layer, that includes node pools, runtime options, isolation features, workload placement, specialized execution modes, and the cluster-owned components or identities that participate in that execution layer. It can also include compute-layer hardening choices that change the security properties of where and how workloads execute. This is also where alternative execution models, such as stronger workload isolation through things like Kata containers, start to matter because they change the security properties of how a workload runs compared to a more traditional container path.

When examined after deployment, this lens helps reveal what execution context a workload receives, which architectural elements influence that context, and what operational or security implications follow from it.

Networking

Networking focuses on how traffic, reachability, and isolation are expressed inside and around the cluster. The main decisions here include API reachability, service exposure, network policy, CNI choices, and cloud-network integration. In practice, this lens helps identify where connectivity exists, what boundaries are enforced, and how network shape influences both control and workload behavior.

Observability

Observability focuses on how cluster behavior becomes visible through logs, events, metrics, audit trails, and other telemetry surfaces. That includes audit configuration, monitoring integrations, runtime and network visibility, and the telemetry components that shape what can or cannot be seen later. In use, it helps reveal what actions generate a footprint, where detection opportunities or blind spots exist, and how assessment tradecraft may need to adapt based on the visibility or invisibility of different behaviors in the environment.

From Mental Model to Cluster Specification

What came next was finding a way to make that mental model usable. In that form, it could be used in two directions: first, to describe and deploy cluster scenarios more deliberately, and second, to read an existing environment back through the same structure during analysis. It made it easier to see where control, access, and influence existed, whether the goal was to understand potential abuse paths or to reason about defensive posture. That is also the point where the model started becoming a framework instead of remaining only an idea.

Codex gave me a way to think through this problem in conversation, pressure-test partial ideas, and shape them into something more explicit over time. It not only helping me explain the model, but it also structured the model enough to turn into a framework I could work with.

In practice, that framework became a specification. It uses YAML as the place where cluster behavior and deployment choices are declared through the same lenses we just walked through above. Instead of filling in a flat list of provider settings, the specification organizes those decisions by meaning. Terraform then takes that specification and realizes it, so the cluster is deployed in the shape that the model describes. That is what makes the framework more than an explanation. It becomes a usable way to define, deploy, and study real cluster scenarios.

One of the easiest ways to illustrate this is to show what a YAML specification looks like. The following example describes a cluster that enables managed Entra authentication, Azure RBAC for Kubernetes authorization, and workload identity for applications:

# Cluster identity and deployment boundary.
name: "aks-entra-azure-rbac-workload-identity-baseline"
subscription_id: "REPLACE_WITH_YOUR_AZURE_SUBSCRIPTION_ID"

cluster_control:
  # Resource group that will contain the AKS control plane resource.
  resource_group:
    mode: "managed"
    name: "rg-aks-entra-azure-rbac-workload-identity-baseline"
    location: "eastus"
  # Kubernetes version to deploy.
  kubernetes_version: "1.34.4"
  # Identity used by the AKS resource in Azure.
  cluster_identity:
    mode: "system_assigned"
  # Bootstrap Entra groups trusted as cluster admins during managed auth.
  bootstrap_admin_groups:
    - mode: "managed"
      display_name: "aks-entra-az-rbac-workload-id-admins"
      mail_nickname: "aksentraazrbacworkloadidadmins"

credential_retrieval:
  # Who can retrieve admin kubeconfig from Azure.
  admin:
    groups:
      - mode: "managed"
        display_name: "aks-entra-az-rbac-workload-id-admin-kubeconfig"
        mail_nickname: "aksentraazrbacworkloadidadminkubeconfig"
    enabled: true
    roles:
      - "Azure Kubernetes Service Cluster Admin Role"
  # Who can retrieve user kubeconfig from Azure.
  user:
    groups:
      - mode: "managed"
        display_name: "aks-entra-az-rbac-workload-id-users"
        mail_nickname: "aksentraazrbacworkloadidusers"
    enabled: true
    roles:
      - "Azure Kubernetes Service Cluster User Role"
  # Whether AKS local static credentials remain available.
  disable_local_accounts: false

authentication:
  # Tenant trusted for managed Entra authentication.
  tenant_id: "<entra-tenant-id>"
  entra_authentication: true

authorization:
  # In-cluster authorization model after authentication succeeds.
  mode: "azure_rbac"
  azure_rbac:
    admin_roles:
      - "Azure Kubernetes Service RBAC Cluster Admin"
    user_roles:
      - "Azure Kubernetes Service RBAC Reader"

admission: {}

workload_management:
  workload_identity:
    # OIDC issuer and workload identity together enable federated pod identity.
    oidc_issuer: true
    workload_identity: true

data_and_storage: {}

computing:
  # Baseline cluster capacity and system node pool settings.
  sku_tier: "Free"
  system_pool:
    node_count: 1
    vm_size: "Standard_B2s"
    os_sku: "Ubuntu"
    vm_set_type: "VirtualMachineScaleSets"

networking:
  # Azure network boundary in which the cluster nodes will live.
  vnet:
    mode: "managed"
    name: "vnet-aks-entra-azure-rbac-workload-identity-baseline"
    address_space:
      - "10.22.0.0/16"
  subnet:
    mode: "managed"
    name: "snet-aks-entra-azure-rbac-workload-identity-baseline"
    address_prefixes:
      - "10.22.1.0/24"
  cluster_network:
    # Kubernetes-facing network behavior layered on top of the Azure network.
    network_plugin: "azure"
    network_plugin_mode: "overlay"
    network_dataplane: "azure"
    load_balancer_sku: "standard"
    outbound_type: "loadBalancer"
    authorized_ip_ranges: []

observability: {}

Terraform is what turns that declaration into a real cluster. In that sense, it acts as the realization layer of the framework. One of the practical lessons from building this was that many improvements could happen at the specification and root translation layer without rewriting every module underneath. That made it possible to keep the provider mechanics relatively stable while improving the meaning and readability of the declaration itself.

At the repo level, the framework separates reusable mechanics from scenario use. That separation matters because it makes the repo understandable on first clone and turns experimentation into a normal workflow instead of an improvised one.

  • modules/ contains the provider realization logic that turns the specification into Azure resources
  • docs/ captures the taxonomy, implementation matrix, and reference explanations that help the reader understand what each choice means
  • templates/ contains copyable profile starting points, including both a generic base profile and scenario-specific templates
  • private-profiles/ is the local workspace where a reader can create a real profile with their own values without mixing that work into the publishable framework

The template catalog is what turns that into a usable system. base-profile works as the comprehensive reference template for the taxonomy-shaped specification, but the practical path is to choose from scenario templates that already encode a particular trust model.

  • local-kubeconfig-baseline keeps the cluster simple and focuses on credential retrieval without adding managed Entra integration inside the cluster
  • entra-auth-baseline introduces managed Entra authentication and a bootstrap admin anchor while keeping in-cluster authorization simpler
  • entra-azure-rbac-workload-identity-baseline adds Azure RBAC for Kubernetes authorization and the federated workload identity path, making it the richest baseline for exploring the full trust stack

Each profile is meant to capture a meaningful increment in the cluster’s trust model.

Using the framework is then straightforward. A user copies one of the working scenario templates into private-profiles/<new-profile-name>, fills in spec.yaml with real values, and applies it from that new private profile directory. That is what makes the specification useful for experimentation. It gives each scenario a stable shape, makes it easier to compare outcomes, preserves the relationship between a research question and the environment used to explore it, and turns each tested profile into both a deployable experiment and a teaching artifact.

From Cluster Specification to Workload Scenarios

The cluster specification defines the environment, but by itself it does not fully reveal how that environment behaves. The next step is to pair the cluster with workloads that exercise the identity paths, access controls, and runtime conditions the specification was designed to support.

The workload side of the framework supports more than one kind of scenario. It includes a native service-account workload, an authentication-focused PoC, and a Key Vault reader that builds on the same authentication mechanics to show what happens when the resulting credential is used against a downstream Azure service. Taken together, those applications make it possible to move from cluster configuration into visible workload behavior.

The Authentication PoC is the clearest place to start because it isolates Azure authentication itself before introducing a second dependency. Its job is to make that path visible. The same FastAPI application is able to support multiple authentication mechanisms, including client secret, certificate, managed identity, and workload identity, depending on how it is deployed and what runtime inputs it receives. The key idea is that the same application can be paired with different identity scenarios without rewriting the code.

_AUTH_SERVICE_REGISTRY = {
    "managed_identity": ManagedIdentityAuth,
    "client_secret": ClientSecretAuth,
    "certificate": CertificateAuth,
    "federated": FederatedAuth,
}

@classmethod
def create(cls, settings: Settings) -> AuthenticationService:
    auth_type = settings.auth_type.lower()
    auth_service_class = cls._AUTH_SERVICE_REGISTRY[auth_type]

    if auth_type == "managed_identity":
        return auth_service_class(
            client_id=settings.managed_identity_client_id,
            azure_scope=settings.azure_scope
        )

    elif auth_type == "client_secret":
        return auth_service_class(
            tenant_id=settings.tenant_id,
            client_id=settings.client_id,
            client_secret=settings.client_secret,
            azure_scope=settings.azure_scope
        )

    elif auth_type == "certificate":
        return auth_service_class(
            tenant_id=settings.tenant_id,
            client_id=settings.client_id,
            certificate_path=settings.certificate_path,
            certificate_password=settings.certificate_password,
            azure_scope=settings.azure_scope
        )

    elif auth_type == "federated":
        return auth_service_class(
            tenant_id=settings.tenant_id,
            client_id=settings.client_id,
            token_file_path=settings.token_file_path,
            federated_token_audience=settings.federated_token_audience,
            azure_scope=settings.azure_scope
        )

This is the point where that idea becomes concrete in the code. The factory makes the application branch into different identity paths without changing the overall application shape. That same design choice extends to the API surface. The application exposes a small set of routes whose job is to help explain the runtime state and the authentication path being exercised:

@router.get("/api/runtime", response_model=RuntimeConfig)
def show_runtime(request: Request) -> RuntimeConfig:
    return auth_service.inspect_runtime_config()

@router.get("/api/auth/explain", response_model=AuthFlowDescription)
def auth_explain(request: Request, scope: str | None = Query(default=None)) -> AuthFlowDescription:
    return auth_service.explain_authentication_flow(scope=scope)

@router.get("/api/auth/test", response_model=AuthTestResult)
def auth_test(request: Request, scope: str | None = Query(default=None)) -> AuthTestResult:
    return auth_service.test_authentication(scope=scope)

@router.get("/api/auth/trace", response_model=AuthTraceResult)
def auth_trace(request: Request, scope: str | None = Query(default=None)) -> AuthTraceResult:
    return auth_service.trace_authentication(scope=scope)

That route surface is part of what makes the application useful for research:

  • /api/runtime lets you inspect the active configuration the workload received at runtime
  • /api/auth/explain describes the path the application expects to take before it requests a token
  • /api/auth/test attempts authentication and returns the result directly
  • /api/auth/trace goes one step deeper and returns a more detailed view of the request path, intermediate steps, and sanitized authentication results so that the runtime behavior can be inspected rather than treated as a black box

Taken together, the credential factory and these API routes create a runtime environment that makes authentication visible instead of implicit. They make it possible to inspect how the application received its inputs, which identity path it selected, how a token request was assembled, and how different authentication mechanisms behave under the same application shape. That matters because many of those details are usually hidden behind the SDK or absorbed into the surrounding platform. Here, the goal is to surface them so we can actually see and understand the flow.

At the repo level, the workload side now follows a similar design lesson to the cluster framework: keep the reusable mechanics stable, then make scenario use explicit and copyable.

  • apps/ is the workload catalog, where each application owns its own source code, containerization, Terraform realization, and Kubernetes deployment material
  • docs/ explains the shared workload contract, including the source code, container, Terraform, and Kubernetes layers
  • Each application keeps the same readable FastAPI shape while exposing a different capability level, such as native service-account introspection, authentication-only testing, or authentication plus downstream Azure service interaction

What makes this usable in practice is that the application code stays stable while the deployment changes around it. Different scenarios may require corresponding Azure or Entra-side resources, and the values that come from those resources are then delivered into the workload through the Kubernetes side. That keeps the code decoupled from the surrounding configuration while still letting the same application participate in very different identity and deployment patterns.

The choice of Python and FastAPI was also intentional. It shaped the architecture of the applications in a way that keeps them readable, didactical, and extensible at the same time. We should be able to look at the code and understand what the application is doing without having to fight through unnecessary abstraction, but the same structure should also be strong enough to carry new behavior as the scenarios evolve.

Beyond the Lab: From Scenarios to Real Environments

One of the larger goals behind this work is to move toward ways of reasoning about cluster identity and access relationships that can better handle scale, change, and more fluid environments. Getting there requires a stable place to explore, test, and understand those mechanics first, so that the resulting understanding can later be carried into tooling, automation, and broader analytical workflows.

Up to this point, we’ve used the framework from the design side. It gave us a way to decide how to configure a cluster so we could create deliberate scenarios and understand the mechanics underneath them. At this stage, those scenarios are no longer only clusters or only workloads. They come from intentionally combining different cluster profiles with different workload variants. That is what makes it possible to take the same application and run it under different authentication mechanisms, runtime inputs, and cluster conditions while preserving enough structure to compare what changed. That is what turns configuration into experimentation and then turns experimentation into something more useful than a lab result.

Once the mechanics are visible, it becomes easier to understand what artifacts they depend on, what control points they create, and how those paths might later be abused, detected, or defended. We can use the same lenses to identify where control, trust, and influence exist, and to reason about attack surface, abuse paths, or defensive boundaries depending on how the environment is being approached.

In practice, this is often the position we start from during an engagement: the cluster already exists inside an organization, and the task is to assess its security posture rather than to decide how it should have been built. At that point, the problem is no longer to declare what should be there, but to recover what decisions were made, what identity relationships are present, and which configurations or trust paths may translate into attack paths in the environment.

This is also where I want to leave room for the work that still needs to happen. Even when we have the chance to inspect a cluster directly and assess its security posture, that assessment is often still a point-in-time view. The cluster keeps changing, and the amount of relevant information can also grow beyond what is easy to reason about directly. New workloads are introduced, configurations drift, and new trust paths or attack paths can appear after the fact. Part of what makes the framework useful to me now is that it gives me a way to keep working on both of those problems deliberately. I can use it to design the scenarios I want to understand and then use those scenarios to build the tools and tradecraft needed to collect and analyze the environment more directly over time.

If you want to explore the framework itself, look at the code, or collaborate on the ideas behind it, I will add links here to the cluster and workload repositories.

Ready to get started?

Book a Demo