Chapter 5

Adapters are where profile demand becomes platform action.

A valid profile is still just a requirements document. The adapter is the platform-specific component that decides how those requirements are satisfied and wired into the workload.

Adapter responsibility

  1. 1
    Read a valid profile.The adapter starts from Conditions and their declared `configuration.env` inputs.
  2. 2
    Validate against platform context.In the demo, API Conditions are checked against a catalog OpenAPI document.
  3. 3
    Invoke provider interfaces.For Redis, S3, and Cilium, the adapter calls the corresponding Promise interface with resolved inputs.
  4. 4
    Bind provider outputs.The adapter maps profile env names to ConfigMaps, Secrets, literal URLs, and policy outputs.
  5. 5
    Render workload deployment.The final Deployment contains target-specific references, but the profile remains target-neutral.

Adapter input: a profile Condition

The adapter is not guessing from the application source. It receives the generated profile and interprets Conditions that have already passed validation.

Cache Condition from the profile
- name: request-cache
  kind: cache
  interface:
    type: key_value
    engine: redis
  configuration:
    alternatives:
      - env:
          - property: url
            name: REDIS_URL
      - env:
          - property: hostname
            name: REDIS_HOST
          - property: port
            name: REDIS_PORT

Adapter step: choose provider outputs for profile properties

The Redis Promise owns Redis provisioning and publishes connection outputs. The adapter only knows how to satisfy profile properties from those outputs.

ApplicationRelease adapter resolver source
redis_env = env_from_configuration(
  condition,
  {
    "url": config_map_value(f"{redis_name}-connection", "url"),
    "hostname": config_map_value(f"{redis_name}-connection", "hostname"),
    "port": config_map_value(f"{redis_name}-connection", "port"),
  },
)
env.extend(redis_env)

Adapter step: validate API compatibility before deployment

The API Condition declares `GET /todos/{id}` and an expected response shape. The adapter compares that requirement with the catalog OpenAPI document before creating the workload.

API validation path
for condition in conditions:
  if condition.get("kind") != "api":
    continue

  api = validate_api_condition(condition, apis)
  base_url = api.base_url or f"http://{api.name}.{namespace}.svc.cluster.local:{port}"

  api_env = env_from_configuration(
    condition,
    {
      "url": literal_value(base_url),
      "baseUrl": literal_value(base_url),
    },
  )

Adapter step: call platform interfaces, not invent a second profile

The adapter should trigger existing provider interfaces directly. In this demo those interfaces are Kratix Promises. The important boundary is that the adapter is not creating another Runtime Conditions document between itself and the Promise.

Profile RequirementAdapter CallsProvider Owns
`kind: cache`, `engine: redis`Redis Promise interfaceRedis Deployment, Service, connection ConfigMap, Redis network policy
`kind: api`, `interface.type: http`CiliumAPIAccess Promise interface after catalog validationCilium policy for declared HTTP methods and paths
`kind: aws.object_store`, `interface.type: aws.s3`S3Bucket Promise interfaceAWS bucket, IAM credentials, connection ConfigMap, credential Secret, S3 egress policy

Provider output: S3 Promise artifacts

The S3 Promise handles AWS. It reads platform-owned admin credentials, creates the real bucket and IAM credentials, then publishes workload-safe Kubernetes outputs.

platform/kratix/promises/s3-bucket/pipeline/configure.py source
connection_config = {
  "kind": "ConfigMap",
  "metadata": {"name": f"{name}-connection", "namespace": namespace},
  "data": {
    "bucket": bucket,
    "region": region,
  },
}

credentials = {
  "kind": "Secret",
  "metadata": {"name": f"{name}-credentials", "namespace": namespace},
  "data": {
    "accessKeyId": b64(aws["accessKeyId"]),
    "secretAccessKey": b64(aws["secretAccessKey"]),
  },
}

Final workload binding

This is where the profile's environment variable names meet platform-provided values. The application still reads the same env vars it declared in source.

Rendered Deployment env entries
env:
  - name: TODOS_API_URL
    value: http://todos-api.demo.svc.cluster.local:8080

  - name: REDIS_URL
    valueFrom:
      configMapKeyRef:
        name: request-logger-cache-connection
        key: url

  - name: AWS_SECRET_ACCESS_KEY
    valueFrom:
      secretKeyRef:
        name: request-logger-object-store-credentials
        key: secretAccessKey

Boundary summary

ComponentOwnsDoes Not Own
GeneratorSource-to-profile extraction.Provisioning, deployment, target values.
AdapterProfile interpretation for one platform.Extension vocabulary or provider internals.
PromiseConcrete provider implementation.Application source analysis or profile generation.