Skip to content

Custom resources

All KIMO resources live in API group kimo.kimo.io/v1alpha1 and are namespaced.

ChallengeTemplate

Defines a challenge: what to run and under what rules. Instances reference a template by name.

apiVersion: kimo.kimo.io/v1alpha1
kind: ChallengeTemplate
metadata:
  name: web-sqli-101
spec:
  category: web              # freeform metadata
  difficulty: easy           # freeform metadata
  points: 100                # freeform metadata
  flagSecretRef:             # required — must exist for the template to be Ready
    name: web-sqli-101-flag
  instanceMode: perTeam      # shared | perTeam | perPlayer
  ttl: 30m                   # required — instance lifetime (Go duration)
  maxInstances: 200          # concurrent-instance cap (0 = unlimited)
  pow:                       # optional proof-of-work gate
    enabled: true
    difficulty: 20           # leading zero bits
    algorithm: sha256
    ttl: 5m                  # puzzle validity
  container:
    image: registry.example.com/challenges/web-sqli:v1   # required
    ports:
      - name: http
        containerPort: 8080
        expose: true         # exposed via Service + allowed through the fence
    resources:
      requests: { cpu: 100m, memory: 128Mi }
      limits: { cpu: 500m, memory: 256Mi }
    env: []                  # standard corev1 EnvVar list
    readiness:
      type: tcp              # tcp | http | none
      port: 8080
      path: /                # http only
    restartPolicy: Always    # only Always (or omitted) is accepted
    unhealthyThreshold: 3    # readiness failures before Unhealthy

Status: ready (validation passed), instanceCount (instances referencing this template), message (why not ready).

ChallengeInstance

One running copy of a challenge for a team/player. Usually created through the REST API, but applying one directly works too.

apiVersion: kimo.kimo.io/v1alpha1
kind: ChallengeInstance
metadata:
  name: web-sqli-101-team-alpha
spec:
  templateRef: web-sqli-101   # required
  team: team-alpha            # required
  player: alice               # optional
  ttlOverride: 2h             # optional — replaces the template's ttl

Status: phase (lifecycle), reason, endpoint (in-cluster service address), startedAt, expiresAt, podName, unhealthyCount.

The instance owns its Deployment, Service, and NetworkFence — deleting the instance cascades to all of them.

ChallengeSet

Groups challenges and activates them inside a time window.

apiVersion: kimo.kimo.io/v1alpha1
kind: ChallengeSet
metadata:
  name: round-1
spec:
  challenges: [web-sqli-101, web-xss-201]   # template names
  schedule:                                  # optional — omit for always-active
    startAt: "2026-09-01T10:00:00Z"          # RFC 3339
    endAt: "2026-09-01T18:00:00Z"

Status: active, message. The controller requeues itself at the next schedule boundary, so sets flip on time without external triggers.

NetworkFence

Network isolation for one instance, rendered as a NetworkPolicy. Auto-created per instance — apply one manually only to add extra rules. See Network isolation.

apiVersion: kimo.kimo.io/v1alpha1
kind: NetworkFence
metadata:
  name: web-sqli-101-team-alpha
spec:
  instanceRef: web-sqli-101-team-alpha   # required — selects pods by kimo.io/instance label
  allowRules:
    - port: 8080
    - cidr: 10.0.0.0/8
  denyRules:
    - to: kimo-system
  allowEgress: false

Status: applied, message.

Labels

KIMO stamps these on everything it creates, and the API's list filters use them:

Label Value
kimo.io/challenge Template name
kimo.io/team Team
kimo.io/instance Instance name