avishayt/csi-driver-interceptor

CSI driver gRPC proxy interceptor - intercepts CSI calls between sidecars and driver for logging and policy enforcement

★ 0Forks 0GoGitHub ↗Compare

README

CSI Driver Interceptor - gRPC Proxy PoC

This PoC demonstrates intercepting CSI driver calls at the gRPC layer by inserting a proxy between CSI sidecar containers and the actual CSI driver.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                  CSI Driver Pod                             │
│                                                             │
│  external-provisioner ─┐                                   │
│  external-attacher     ├─→ /csi/csi.sock                   │
│  external-resizer      ─┘       ↓                          │
│                         ┌───────────────────┐               │
│                         │  Interceptor Proxy │              │
│                         │  - Logs all RPCs   │              │
│                         │  - Policy checks   │              │
│                         │  - Can reject      │              │
│                         └───────────────────┘               │
│                                 ↓                           │
│                         /driver/csi.sock                    │
│                                 ↓                           │
│                         ┌───────────────────┐               │
│                         │   Real CSI Driver  │              │
│                         │   (hostpath-csi)   │              │
│                         └───────────────────┘               │
└─────────────────────────────────────────────────────────────┘

How It Works

  1. Proxy Socket: Sidecars connect to /csi/csi.sock (interceptor)
  2. Driver Socket: Real driver binds to /driver/csi.sock
  3. gRPC Proxy: Implements csi.ControllerServer and csi.NodeServer
  4. Request Flow: Log → Policy Check → Forward → Log Response
  5. Policy Rejection: Returns gRPC error codes (PermissionDenied, ResourceExhausted)

Intercepted Operations

Controller Service

  • ✅ CreateVolume / DeleteVolume
  • ✅ ControllerPublishVolume / ControllerUnpublishVolume
  • ✅ CreateSnapshot / DeleteSnapshot
  • ✅ ControllerExpandVolume
  • ✅ ListVolumes, GetCapacity, ValidateVolumeCapabilities

Node Service

  • ✅ NodePublishVolume / NodeUnpublishVolume
  • ✅ NodeStageVolume / NodeUnstageVolume
  • ✅ NodeExpandVolume
  • ✅ NodeGetVolumeStats, NodeGetCapabilities, NodeGetInfo

Policy Framework

Current: No-Op Checker

Allows all operations (for basic PoC testing)

Example: Quota Checker

policy := policy.NewQuotaChecker(10 * 1024 * 1024 * 1024) // 10GB max
// Rejects CreateVolume if size > 10GB

Future: OSAC Integration

type OSACPolicyChecker struct {
    controlPlaneClient osac.Client
}

func (o *OSACPolicyChecker) CheckCreateVolume(ctx, req) error {
    // Call OSAC control plane
    allowed, err := o.controlPlaneClient.CheckQuota(...)
    if !allowed {
        return status.Error(codes.ResourceExhausted, "quota exceeded")
    }
    return nil
}

Building

go build -o csi-proxy cmd/proxy/main.go

Running Locally (for testing)

# Terminal 1: Start a mock CSI driver on /driver/csi.sock
# (or use real hostpath driver)

# Terminal 2: Start the proxy
./csi-proxy \
  --proxy-socket=/tmp/csi.sock \
  --driver-socket=/driver/csi.sock \
  --logger-url=http://localhost:8080/log

# Terminal 3: Test with csc (CSI command-line tool)
csc controller create-volume test-vol --endpoint=unix:///tmp/csi.sock

Deployment (Kubernetes)

The proxy runs as a sidecar in the CSI driver pod:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: csi-hostpath-driver
spec:
  template:
    spec:
      containers:
      # CSI sidecars connect to /csi/csi.sock
      - name: external-provisioner
        volumeMounts:
        - name: socket-dir
          mountPath: /csi
      
      # Interceptor proxy
      - name: csi-interceptor
        image: csi-interceptor:latest
        args:
        - --proxy-socket=/csi/csi.sock
        - --driver-socket=/driver/csi.sock
        volumeMounts:
        - name: socket-dir
          mountPath: /csi
        - name: driver-socket-dir
          mountPath: /driver
      
      # Real driver binds to /driver/csi.sock
      - name: hostpath-driver
        args:
        - --endpoint=unix:///driver/csi.sock
        volumeMounts:
        - name: driver-socket-dir
          mountPath: /driver
      
      volumes:
      - name: socket-dir
        emptyDir: {}
      - name: driver-socket-dir
        emptyDir: {}

Logged Events

Each CSI RPC produces two log entries:

Request:

{
  "timestamp": "2026-05-20T12:34:56Z",
  "direction": "request",
  "method": "CreateVolume",
  "parameters": {
    "name": "pvc-12345",
    "capacity": "1073741824"
  }
}

Response:

{
  "timestamp": "2026-05-20T12:34:57Z",
  "direction": "response",
  "method": "CreateVolume",
  "parameters": {
    "volume_id": "vol-abcdef"
  },
  "latency": "123ms"
}

Policy Rejection:

{
  "timestamp": "2026-05-20T12:35:00Z",
  "direction": "response",
  "method": "CreateVolume",
  "error": "rpc error: code = ResourceExhausted desc = quota exceeded",
  "latency": "5ms"
}

Comparison with Webhook Approach

Aspect gRPC Proxy (this PoC) Admission Webhook
Interception Point CSI driver gRPC calls Kubernetes API
Visibility Full CSI operation details PVC/VolumeAttachment metadata only
Can Modify Can modify RPC params Can reject, not modify
Driver Agnostic Works with ANY CSI driver Works regardless of driver
Deployment Inject into driver pod Separate webhook deployment
Latency Per-RPC overhead Per-API-call overhead
Policy Scope Driver-level (size, IOPS) Resource-level (quota, tenant)

Use Cases

  1. Audit Logging: Track all volume operations with full context
  2. Policy Enforcement: Reject operations based on OSAC control plane decisions
  3. Testing: Inject failures, delays for chaos engineering
  4. Multi-Tenancy: Enforce tenant isolation at driver level
  5. Quota Management: Reject over-quota volume creates
  6. Performance Monitoring: Track CSI RPC latencies

Limitations

  1. Requires modifying CSI driver deployment (socket paths)
  2. Adds latency to every CSI operation
  3. Must implement all CSI RPC methods (even if just pass-through)
  4. Identity service currently pass-through (could intercept too)

Future Enhancements

  • Implement full Identity service interception
  • Add metrics (Prometheus)
  • Support bidirectional streaming RPCs
  • Add request/response caching
  • Circuit breaker for driver failures
  • Rate limiting per tenant
  • Integration with OSAC control plane API

License

Apache 2.0

Contributors

avishayt

Issues