Gravitee · Capability

Gravitee Agent Onboarding

Gravitee Agent Onboarding — automated agent self-registration across Gravitee APIM and Gravitee AM (the only Tier 1 gateway in the field with both API management and access management in one product family). Plan-based scope (the cleanest gateway-native scope abstraction), native audit on both APIM logs and AM audits, suitable for fully customer-hosted, open-core deployments. 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.

Run with Naftiko GraviteeGravitee APIMGravitee AMAgent OnboardingPlansNative AuditOpen SourceNaftiko Capability

What You Can Do

POST
Onboardagent
/v1/agents/onboard
POST
Revokeagent
/v1/agents/{agent_id}/revoke

MCP Tools

agent-register

agent-revoke

idempotent

Capability Spec

gravitee-agent-onboarding.yaml Raw ↑
naftiko: 1.0.0-alpha2
info:
  label: Gravitee Agent Onboarding
  description: 'Gravitee Agent Onboarding — automated agent self-registration across Gravitee
    APIM and Gravitee AM (the only Tier 1 gateway in the field with both API management and
    access management in one product family). Plan-based scope (the cleanest gateway-native
    scope abstraction), native audit on both APIM logs and AM audits, suitable for fully
    customer-hosted, open-core deployments. 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:
  - Gravitee
  - Gravitee APIM
  - Gravitee AM
  - Agent Onboarding
  - Plans
  - Native Audit
  - Open Source
  - 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/gravitee
binds:
- namespace: env
  keys:
    GRAVITEE_APIM_BASE_URI: GRAVITEE_APIM_BASE_URI
    GRAVITEE_AM_BASE_URI: GRAVITEE_AM_BASE_URI
    GRAVITEE_ENV_ID: GRAVITEE_ENV_ID
    GRAVITEE_ORG_ID: GRAVITEE_ORG_ID
    GRAVITEE_DOMAIN: GRAVITEE_DOMAIN
    GRAVITEE_ADMIN_TOKEN: GRAVITEE_ADMIN_TOKEN
    AGENT_TRUSTED_ISSUERS: AGENT_TRUSTED_ISSUERS
    AGENT_CONSENT_HASH: AGENT_CONSENT_HASH
capability:
  consumes:
  - type: http
    namespace: gravitee-apim
    baseUri: '{{env.GRAVITEE_APIM_BASE_URI}}'
    description: Gravitee APIM — applications, subscriptions, API keys, plans, logs.
    resources:
    - name: env-applications
      path: /environments/{envId}/applications
      operations:
      - name: createapplication
        method: POST
        description: Create the agent's application entity.
        outputRawFormat: json
        outputParameters:
        - { name: result, type: object, value: $. }
        inputParameters:
        - { name: envId, in: path, type: string, required: true }
        - { name: body, in: body, type: object, required: true }
    - name: app-subscriptions
      path: /environments/{envId}/applications/{appId}/subscriptions
      operations:
      - name: createsubscription
        method: POST
        description: Subscribe the application to the scope-tier plan. The plan's
          rate-limit and ACL policies attach automatically.
        outputRawFormat: json
        outputParameters:
        - { name: result, type: object, value: $. }
        inputParameters:
        - { name: envId, in: path, type: string, required: true }
        - { name: appId, in: path, type: string, required: true }
        - { name: body, in: body, type: object, required: true }
    - name: subscription-apikeys
      path: /environments/{envId}/subscriptions/{subId}/apikeys
      operations:
      - name: createapikey
        method: POST
        description: Mint an API key tied to the subscription. Revocation via
          DELETE on the apikey resource.
        outputRawFormat: json
        outputParameters:
        - { name: result, type: object, value: $. }
        inputParameters:
        - { name: envId, in: path, type: string, required: true }
        - { name: subId, in: path, type: string, required: true }
    - name: logs-search
      path: /environments/{envId}/logs/search
      operations:
      - name: searchlogs
        method: POST
        description: APIM-side audit observation — runtime traffic logs.
        outputRawFormat: json
        outputParameters:
        - { name: result, type: object, value: $. }
    authentication:
      type: bearer
      token: '{{env.GRAVITEE_ADMIN_TOKEN}}'
  - type: http
    namespace: gravitee-am
    baseUri: '{{env.GRAVITEE_AM_BASE_URI}}'
    description: Gravitee AM — access management surface for identity-level audit
      and policy. The Web Bot Auth signature flows through AM's organization audit stream.
    resources:
    - name: org-audits
      path: /organizations/{organizationId}/audits
      operations:
      - name: listorgaudits
        method: GET
        description: Identity-side audit stream — captures the who-onboarded-whom record
          that complements APIM's what-was-called record.
        outputRawFormat: json
        outputParameters:
        - { name: result, type: object, value: $. }
        inputParameters:
        - { name: organizationId, in: path, type: string, required: true }
    authentication:
      type: bearer
      token: '{{env.GRAVITEE_ADMIN_TOKEN}}'
  orchestration:
  - name: onboard-agent
    description: Verify identity, ensure the scope-tier plan exists, create application,
      subscribe to plan, mint API key, observe audit across both APIM and AM streams.
    inputs:
    - { name: signature, type: object, required: true }
    - { name: signature_agent, type: string, required: true }
    - { name: skill_id, type: string, required: true }
    - { name: requested_scopes, type: array, required: true, description: 'Each scope identifies one plan name.' }
    - { 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: classify_scopes
      type: builtin.policy.scope-classify
      with:
        requested: '${input.requested_scopes}'
    - id: create_application
      call: gravitee-apim.createapplication
      with:
        envId: '{{env.GRAVITEE_ENV_ID}}'
        body:
          name: 'agent-app-${steps.verify_signature.agent_id}'
          description: 'Auto-created by Naftiko agent-onboarding capability'
          type: SIMPLE
          settings:
            app:
              client_id: '${steps.verify_signature.agent_id}'
          metadata:
            operator: '${input.contact.operator}'
            skill_id: '${input.skill_id}'
    - id: subscribe_to_plan
      call: gravitee-apim.createsubscription
      description: Plan is the scope primitive — one subscription to the scope-tier plan
        gates which APIs the agent can call and at what rate.
      with:
        envId: '{{env.GRAVITEE_ENV_ID}}'
        appId: '${steps.create_application.id}'
        body:
          plan: '${steps.classify_scopes.target}'
          request: 'Agent ${steps.verify_signature.agent_id} onboarded via Naftiko capability'
    - id: mint_apikey
      call: gravitee-apim.createapikey
      with:
        envId: '{{env.GRAVITEE_ENV_ID}}'
        subId: '${steps.subscribe_to_plan.id}'
    - id: emit_audit
      description: Gravitee AM emits an organization audit event automatically for
        application + subscription creation; the orchestration annotates the application
        metadata with the consent_hash and signature_keyid so the AM audit stream is
        queryable for the full agent-identity record.
      type: builtin.audit.observe
      with:
        target: gravitee-am.listorgaudits
        annotate_with:
          agent_id: '${steps.verify_signature.agent_id}'
          operator: '${input.contact.operator}'
          consent_hash: '${input.consent_hash}'
          signature_keyid: '${steps.verify_signature.keyid}'
    output:
      agent_id: '${steps.verify_signature.agent_id}'
      application_id: '${steps.create_application.id}'
      subscription_id: '${steps.subscribe_to_plan.id}'
      credential:
        type: Bearer
        header: X-Gravitee-Api-Key
        value: '${steps.mint_apikey.key}'
        revocation_url: '/v1/agents/${steps.verify_signature.agent_id}/revoke'
      scope_tier: '${steps.classify_scopes.target}'
  - name: revoke-agent
    description: Delete the application; cascades to subscription and API key.
    inputs:
    - { name: application_id, type: string, required: true }
    steps:
    - id: delete_app
      type: builtin.delete
      with:
        target: gravitee-apim.env-applications
        id: '${input.application_id}'
    output:
      revoked: true
  exposes:
  - type: rest
    namespace: gravitee-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: gravitee-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: gravitee-agent-onboarding-skill
    description: 'Agent skill at /skills/onboard-agent.md. Gravitee-specific addendum:
      the scope name is a Plan name; the agent expresses scope intent as a single plan
      rather than per-operation tags.'
    skill:
      name: onboard-agent
      file: skills/onboard-agent.md