Every system gets a plugin.

A plugin is a Go package for one system. It reads state, takes in telemetry, publishes into the graph, and can declare the fixes it knows how to apply.

In the box.

  • Kubernetes

    Owns API discovery and one shared informer per resource type, covering workloads, services, RBAC, and admission configuration. Publishes one collection per type and reuses it for every plugin that asks.

    Secrets arrive as metadata and a sorted list of key names. Values, type, and annotations are excluded.

    • Discovery
    • Remediation

    Can apply: NetworkPolicy ingress isolation for a Pod or a Service

  • Istio

    Models AuthorizationPolicy, PeerAuthentication, ambient enrollment, waypoints, ServiceEntry, and VirtualService on top of the Kubernetes plugin’s watches.

    Maps waypoint OTLP access logs into bounded communication rollups. It needs a custom access-log provider that emits agentshield attributes, and only Deployment callers resolve.

    ServiceEntry endpoint values stay out of the graph; only counts and address classes are kept.

    • Discovery
    • Telemetry
    • Remediation

    Can apply: STRICT mutual TLS with PeerAuthentication

  • Cilium

    Reads CiliumNetworkPolicy, CiliumClusterwideNetworkPolicy, CiliumEndpoint, and CiliumNode, and enriches the matching pods and nodes instead of creating rival identities.

    A Hubble flow normalizer exists. Nothing feeds it yet.

    CNI state and flows only. Service mesh, Envoy, and L7 policy are out of scope.

    • Discovery
    • Remediation

    Can apply: CiliumNetworkPolicy ingress isolation

  • agentgateway

    Early

    Projects GatewayClass, Gateway, HTTPRoute, and the Services they reference for agentgateway instances managed through Gateway API.

    An access-log normalizer exists. Nothing feeds it yet.

    Early. Expect it to change.

    • Discovery
  • Falco

    Early

    Maps Falco alerts that an existing OpenTelemetry Collector forwards to the shared OTLP receiver. It opens no provider connection and owns no inventory.

    Turns a terminal-shell alert into a process-exec event. The Pod gains an executes edge to the shell process class, and a rule can match on it.

    Early. One use case: a Pod started an interactive shell. Command lines and user names are never copied.

    • Telemetry
  • AWS

    Early

    Inventories EC2 instances, network interfaces, and security groups in one region. It reconciles at startup and every five minutes, and CloudTrail events delivered through EventBridge and SQS trigger a reconcile right away.

    Takes VPC Flow Logs straight from Amazon Data Firehose, with no collector in between.

    Early. EC2 only: no routing, gateways, network ACLs, or IAM, and no fixes it can apply.

    • Discovery
    • Telemetry

Planned, not shipped.

More runtime signals are next. Nothing here is in this release.

  • Tetragon

    Runtime events from eBPF

Write one.

A plugin declares what it owns, consumes collections, and replaces its contribution as the world changes. The sample is from the plugin guide.

  • Projectors are pure. Current objects in, graph input out, same result whatever the input order.
  • Identity is authority plus an immutable key. Names and addresses are attributes.
  • Every assertion names its source. Plugin, source, rule ID, and evidence IDs.
  • Replace, never patch. Publish the complete current output. What you omit is retracted.
  • Telemetry stays out of the graph. Only bounded rollups with resolved endpoints are projected.
func New() (*Plugin, error) {  foos, err := kubernetes.NewResourceClient(kubernetes.ResourceRequirement{    GVR:        schema.GroupVersionResource{Group: "foo.example.io", Version: "v1", Resource: "foos"},    Capability: "foo-v1",  }, decodeFoo)  if err != nil {    return nil, err  }  return &Plugin{foos: foos}, nil}func (p *Plugin) KubernetesResources() []kubernetes.ResourceRequirement {  return []kubernetes.ResourceRequirement{p.foos.Requirement()}}func (p *Plugin) Descriptor() discovery.Descriptor {  return discovery.Descriptor{    ID:          "foo",    Version:     "1.0.0",    Description: "Foo security semantics",    Consumes:    []string{p.foos.Collection()},    Publishes:   []string{"foo/projection"},  }}

Only one plugin may publish a collection name, and every consumed collection needs a publisher. The manager checks both before anything starts.

Run it yourself.

One binary with the explorer built in. It needs PostgreSQL and something to read: a Kubernetes context, AWS credentials, or both. The model is optional.

Needs Go, Node.js with pnpm, Docker, and kubectl.

No cluster? The demo runs the real UI against fake data in your browser. Try the demo

export POSTGRES_PASSWORD='development-only-password'make postgres-upexport AGENTSHIELD_DATABASE_URL="postgres://agentshield:${POSTGRES_PASSWORD}@127.0.0.1:5432/agentshield?sslmode=disable"make run

Open http://127.0.0.1:8088. For findings, point it at a model and turn on agentic investigation, then run make run again.

export AGENTSHIELD_MODEL_ENDPOINT='https://api.openai.com'export OPENAI_API_KEY='<your key>'export AGENTSHIELD_AGENTIC_INVESTIGATION=true