naftiko: 1.0.0-alpha2 info: label: Deutsche Telekom / CAMARA Agent Onboarding (Carrier-Grade) description: 'Deutsche Telekom + CAMARA Agent Onboarding — carrier-grade pattern. Differs fundamentally from SaaS-gateway adapters because telecom-network APIs require legal-entity operator attestation, per-API-call user consent flows, regulatory audit retention, and rate limits measured in carrier-network terms. Three-layer trust model: operator (carrier knows who is calling), agent (Web Bot Auth identifies the specific agent), call (end-user authorizes this specific lookup). Runtime policy enforcement (signature verify, consent check, scope classify, audit emit) lives in the orchestration.steps below — each step that gates issuance carries on_failure: deny. Lint-time validation of this capability shape lives in the companion Polychro ruleset at https://github.com/api-evangelist/posts/blob/main/polychro/agent-onboarding-rules.yaml — Polychro is Naftiko''s governance layer, separate from the capability spec, and is the correct home for cross-object consistency rules that apply across every agent-onboarding capability.' tags: - Deutsche Telekom - CAMARA - Open Gateway - Telco Network APIs - Agent Onboarding - Carrier-Grade - Per-Call Consent - Regulatory Audit - Naftiko Capability created: '2026-05-28' modified: '2026-05-28' related: - https://apievangelist.com/2026/05/27/automated-agent-onboarding-is-a-naftiko-capability-not-a-gateway-feature/ - https://github.com/api-evangelist/deutsche-telekom - https://github.com/api-evangelist/camara-project binds: - namespace: env keys: DT_PORTAL_BASE_URI: DT_PORTAL_BASE_URI DT_OPERATOR_TOKEN: DT_OPERATOR_TOKEN DT_OPERATOR_AGREEMENT_ID: DT_OPERATOR_AGREEMENT_ID REGULATORY_AUDIT_BUCKET: REGULATORY_AUDIT_BUCKET REGULATORY_AUDIT_RETENTION_YEARS: REGULATORY_AUDIT_RETENTION_YEARS AGENT_TRUSTED_ISSUERS: AGENT_TRUSTED_ISSUERS AGENT_CONSENT_HASH: AGENT_CONSENT_HASH capability: consumes: - type: http namespace: dt-developer-portal baseUri: '{{env.DT_PORTAL_BASE_URI}}' description: DT developer portal — agent registration under an existing operator agreement, per-API subscription, and per-call consent flow initiation. resources: - name: operator-agents path: /developer-portal/operators/{opId}/agents operations: - name: registeragent method: POST description: Register an agent under the operator's pre-existing master agreement. Returns agent_id + client credentials. Operator agreement is a separate one-time legal flow that establishes the trust anchor. outputRawFormat: json outputParameters: - { name: result, type: object, value: $. } inputParameters: - { name: opId, in: path, type: string, required: true } - { name: body, in: body, type: object, required: true } - name: deleteagent method: DELETE description: Revoke agent registration. outputRawFormat: json outputParameters: - { name: result, type: object, value: $. } - name: agent-subscriptions path: /developer-portal/agents/{agentId}/subscriptions operations: - name: createsubscription method: POST description: Subscribe the agent to a specific CAMARA API. Each subscription is scope-tier-bound (which APIs, what call volume, what categories of subscriber data the agent may query). outputRawFormat: json outputParameters: - { name: result, type: object, value: $. } inputParameters: - { name: agentId, in: path, type: string, required: true } - { name: body, in: body, type: object, required: true } - name: consent-flows path: /consent-flows/{flowType} operations: - name: getconsentflow method: GET description: Retrieve the consent-flow definition for a CAMARA API (number verification, location, SIM swap, etc.). Many flows are three-legged OAuth requiring per-end-user authorization at call time. outputRawFormat: json outputParameters: - { name: result, type: object, value: $. } - name: consent-sessions path: /consent-flows/{flowType}/sessions operations: - name: initiateconsentsession method: POST description: Initiate a per-end-user consent session at call time — distinct from the agent-onboarding flow but invoked from the same capability surface. outputRawFormat: json outputParameters: - { name: result, type: object, value: $. } authentication: type: bearer token: '{{env.DT_OPERATOR_TOKEN}}' - type: http namespace: regulatory-archive baseUri: https://archive.{{env.DT_PORTAL_BASE_URI}} description: Regulatory audit archive — separate from observability streams. Long-retention immutable storage for legal record-keeping (typically 7-10 years). resources: - name: events path: /events operations: - name: writeevent method: POST description: Write a regulatory audit record with retention controls. outputRawFormat: json outputParameters: - { name: result, type: object, value: $. } inputParameters: - { name: body, in: body, type: object, required: true } authentication: type: bearer token: '{{env.DT_OPERATOR_TOKEN}}' orchestration: - name: onboard-agent description: Phase 2 onboarding — assumes Phase 1 (operator master agreement) is already complete. Verifies Web Bot Auth, registers agent under operator, subscribes to requested CAMARA APIs, emits to both observability and regulatory archive streams. Phase 3 (per-API call consent) is initiated at runtime via the same capability's initiateconsentsession surface. inputs: - { name: signature, type: object, required: true } - { name: signature_agent, type: string, required: true } - { name: operator_id, type: string, required: true, description: 'Operator must hold an active master agreement with the carrier — Phase 1.' } - { name: skill_id, type: string, required: true } - { name: requested_apis, type: array, required: true, description: 'CAMARA APIs the agent will call (number-verification, device-location, sim-swap, etc.).' } - { name: consent_hash, type: string, required: true } - { name: contact, type: object, required: true } steps: - id: verify_signature type: builtin.web-bot-auth.verify with: signature: '${input.signature}' agent: '${input.signature_agent}' trusted_issuers: '{{env.AGENT_TRUSTED_ISSUERS}}' on_failure: deny - id: verify_consent type: builtin.policy.assert with: assert: '${input.consent_hash} == {{env.AGENT_CONSENT_HASH}}' on_failure: deny - id: verify_operator_agreement type: builtin.policy.assert description: Confirm the operator's master agreement is active and current. with: assert: '${input.operator_id} == {{env.DT_OPERATOR_AGREEMENT_ID}}' on_failure: deny - id: classify_apis type: builtin.policy.scope-classify description: Map requested CAMARA APIs against the operator's agreement-permitted API list. Apis outside the agreement are deny. with: requested: '${input.requested_apis}' - id: register_agent call: dt-developer-portal.registeragent with: opId: '${input.operator_id}' body: name: 'agent-${steps.verify_signature.agent_id}' operator_email: '${input.contact.operator}' support_url: '${input.contact.support_url}' purpose: '${input.contact.purpose}' skill_id: '${input.skill_id}' - id: subscribe_apis type: builtin.for-each description: One subscription per requested CAMARA API. with: items: '${steps.classify_apis.auto}' do: - id: subscribe call: dt-developer-portal.createsubscription with: agentId: '${steps.register_agent.agent_id}' body: api: '${item.api}' rate_limit_subscribers_per_day: '${item.subscribers_per_day_cap}' consent_flow_type: '${item.consent_flow}' - id: emit_observability_audit type: builtin.audit.emit description: Operational observability stream for monitoring and incident response. with: target: dt-developer-portal.agent-subscriptions custom_event: event_type: agent.onboarded agent_id: '${steps.verify_signature.agent_id}' operator_id: '${input.operator_id}' apis: '${steps.classify_apis.auto}' - id: emit_regulatory_audit call: regulatory-archive.writeevent description: Regulatory archive — separate immutable stream with long retention. This is the record national regulators will inspect. with: body: event_type: agent.registered regulator_inspectable: true retention_years: '{{env.REGULATORY_AUDIT_RETENTION_YEARS}}' agent_id: '${steps.verify_signature.agent_id}' operator_id: '${input.operator_id}' contact: '${input.contact}' apis: '${steps.classify_apis.auto}' consent_hash: '${input.consent_hash}' signature_keyid: '${steps.verify_signature.keyid}' signature_alg: '${steps.verify_signature.alg}' timestamp: '${now.iso}' output: agent_id: '${steps.verify_signature.agent_id}' operator_id: '${input.operator_id}' subscription_ids: '${steps.subscribe_apis.results}' credential: type: OAuth2-ClientCredentials client_id: '${steps.register_agent.client_id}' client_secret: '${steps.register_agent.client_secret}' revocation_url: '/v1/agents/${steps.verify_signature.agent_id}/revoke' per_call_consent_required: '${steps.classify_apis.auto[*].consent_flow}' regulatory_audit_id: '${steps.emit_regulatory_audit.id}' - name: revoke-agent description: Revoke agent registration; subscriptions cascade. inputs: - { name: operator_id, type: string, required: true } - { name: agent_id, type: string, required: true } steps: - id: delete_agent call: dt-developer-portal.deleteagent with: opId: '${input.operator_id}' agentId: '${input.agent_id}' - id: emit_revoke_audit call: regulatory-archive.writeevent with: body: event_type: agent.revoked agent_id: '${input.agent_id}' operator_id: '${input.operator_id}' timestamp: '${now.iso}' output: revoked: true exposes: - type: rest namespace: dt-camara-agent-onboarding-rest port: 8080 resources: - path: /v1/agents/onboard operations: - { method: POST, name: onboardagent, call: orchestration.onboard-agent } - path: /v1/agents/{agent_id}/revoke operations: - { method: POST, name: revokeagent, call: orchestration.revoke-agent } - type: mcp namespace: dt-camara-agent-onboarding-mcp port: 9090 transport: http tools: - name: agent-register hints: { readOnly: false, destructive: false, idempotent: false } call: orchestration.onboard-agent - name: agent-revoke hints: { readOnly: false, destructive: true, idempotent: true } call: orchestration.revoke-agent - type: agent-skill namespace: dt-camara-agent-onboarding-skill description: 'Agent skill at /skills/onboard-agent.md. CAMARA-specific addendum: Phase 1 (operator master agreement) is one-time and requires human + legal involvement; only Phase 2 (per-agent registration) is automated by this capability. Per-call consent (Phase 3) is the agent''s responsibility at runtime per the consent-flow definition returned for each subscribed API.' skill: name: onboard-agent file: skills/onboard-agent.md