Skip to content

Conversation

perrozzi
Copy link
Contributor

@perrozzi perrozzi commented Sep 9, 2025

Summary

Adds support for the x-utcp-auth OpenAPI extension that enables seamless authentication inheritance from manual call templates, providing fine-grained per-operation auth control while maintaining backward compatibility.

Problem Solved

  • OpenAPI converter only processed standard security schemes, limiting UTCP-specific auth requirements
  • Users needed a way to configure authentication at the manual call template level and have it automatically inherited by generated tools
  • Required per-operation auth override capability without breaking existing specs

Key Features

  • x-utcp-auth Extension: Per-operation authentication override via custom OpenAPI extension
  • Authentication Inheritance: Tools automatically inherit auth from parent manual call templates when no OpenAPI security is defined
  • Clear Precedence: x-utcp-auth → OpenAPI security → Inherited auth → No auth
  • Smart Reuse: When x-utcp-auth is used, it reuses inherited auth values if compatible, otherwise generates placeholders
  • Case-Insensitive Headers: Normalized header name comparison for better compatibility
  • Safe Type Handling: Guards against malformed x-utcp-auth values
  • Backward Compatibility: Existing OpenAPI security schemes continue to work unchanged

Actual Precedence (in order):

  1. x-utcp-auth extension (if present) - always takes precedence
  2. Standard OpenAPI security (if no x-utcp-auth but security schemes exist)
  3. Inherited auth (if no x-utcp-auth AND no OpenAPI security)
  4. No auth (if none of the above)

Usage Example

x-utcp-auth is a novel extension field created by this PR specifically for UTCP
• It's an optional OpenAPI extension (following OpenAPI's x-* extension pattern) that maintains backward compatibility
• The UTCP converter recognizes and processes this extension during conversion
• It gets consumed and transformed into standard UTCP auth based on the precedence rules

  1. Manual Call Template Configuration:
{
  "manual_call_templates": [{
    "name": "github_api", 
    "call_template_type": "http",
    "url": "https://api.github.com/openapi.json",
    "auth": {
      "auth_type": "api_key",
      "api_key": "Bearer ghp_xxxxxxxxxxxx",
      "var_name": "Authorization",
      "location": "header"
    }
  }]
}
  1. OpenAPI Spec with Novel x-utcp-auth Extension (Create as transient step by the UTCP converter, but could be also defined inside an UTCP-friendly OpenAPI spec):
    This PR introduces support for the new x-utcp-auth extension field that API providers can optionally add to their OpenAPI specifications for UTCP-specific authentication control:
{
  "paths": {
    "/user/repos": {
      "get": {
        "operationId": "list_user_repos",
        "x-utcp-auth": {
          "auth_type": "api_key",
          "var_name": "Authorization", 
          "location": "header"
        }
      }
    }
  }
}

Note: This extension is backward-compatible with OpenAPI standards, so it could be included in an OpenAPI spec and would be ignored by non-UTCP tools.

  1. Generated UTCP Tool (Final Result):
    The UTCP converter processes the x-utcp-auth extension and applies the precedence rules to generate tools with concrete authentication:
{
  "name": "list_user_repos",
  "tool_call_template": {
    "auth": {
      "auth_type": "api_key", 
      "api_key": "Bearer ghp_xxxxxxxxxxxx",  // ← Inherited from manual call template
      "var_name": "Authorization",
      "location": "header"
    }
  }
}

All generated tools automatically inherit the GitHub token authentication without requiring environment variables or additional configuration.

Testing

  • ✅ 7 new comprehensive test cases covering all inheritance scenarios
  • ✅ All existing tests pass (97/97)
  • ✅ Backward compatibility verified

Files Changed

  • openapi_converter.py: Core implementation of auth inheritance and x-utcp-auth extension
  • http_communication_protocol.py: Pass manual call template auth to converter
  • test_x_utcp_auth_extension.py: Comprehensive test coverage

cubic-dev-ai[bot]

This comment was marked as resolved.

@perrozzi
Copy link
Contributor Author

addresses #65

Add support for the x-utcp-auth extension in OpenAPI specifications with seamless
authentication inheritance from manual call templates.

## Features
- Support x-utcp-auth extension that takes precedence over standard security schemes
- Inherit authentication configuration from manual call templates
- Case-insensitive header name comparison for auth inheritance compatibility
- Safe handling of non-dict x-utcp-auth values
- Fall back to placeholder generation when auth is incompatible
- Maintain backward compatibility with existing OpenAPI security

## Usage Example
Manual call template with auth:
```json
{
  "manual_call_templates": [{
    "name": "aws_api",
    "call_template_type": "http",
    "url": "https://api.example.com/openapi.json",
    "auth": {
      "auth_type": "api_key",
      "api_key": "Bearer token-123",
      "var_name": "Authorization",
      "location": "header"
    }
  }]
}
```

OpenAPI operations with x-utcp-auth extension:
```json
{
  "paths": {
    "/protected": {
      "get": {
        "operationId": "get_protected_data",
        "x-utcp-auth": {
          "auth_type": "api_key",
          "var_name": "Authorization",
          "location": "header"
        }
      }
    }
  }
}
```

Generated tools automatically inherit the auth from manual call templates.
@perrozzi perrozzi force-pushed the feature/x-utcp-auth-extension branch from 13cc21d to 5f519b7 Compare September 10, 2025 07:51
@perrozzi perrozzi changed the base branch from main to dev September 10, 2025 09:05
@h3xxit
Copy link
Member

h3xxit commented Sep 10, 2025

Ah wait actually, I just look over the code.
I think what you're proposing doesnt quite work

@h3xxit
Copy link
Member

h3xxit commented Sep 10, 2025

If we put the auth in the manual auth, then the request to the /openapi endpoint will be authenticated. Which doesn't make sense, if the actual openapi endpoint is an open GET request

@h3xxit
Copy link
Member

h3xxit commented Sep 10, 2025

Wouldn't it work to just add this to the openapi spec?

{
  "paths": {
    "/protected": {
      "get": {
        "operationId": "get_protected_data",
        "x-utcp-auth": {
          "auth_type": "api_key",
          "api_key": "Bearer $TOKEN",
          "var_name": "Authorization", 
          "location": "header"
        }
      }
    }
  }
}

In which case there is no inheritance, its just a way to define security following the UTCP way of doing it

@perrozzi
Copy link
Contributor Author

perrozzi commented Sep 10, 2025

my point is the following:

  • Yes /openapi endpoints will be authenticated. That would not be needed if the actual openapi endpoint is an open GET request, but could also be a protected endpoint. The question is if sending auth to an open endpoint has some deeper security implications or not. If there is not need for auth and we send it, it will just be discarded
  • Adding "x-utcp-auth" to the openapi spec would require the OpenAPI to be UTCP-friendly and in most of the cases to be modified to comply with requirements. Existing OpenAPI specs containing endpoints that require authentications will require to build a local UTCP manual or to add an utcp endpoint
  • I am targeting use cases for services like any software around (just to name a few examples: spotify, github itself, etc) cwhere OpenAPIs are hosted out there somewhere, and we want UTCP to simply ingest the OpenAPI spec via a manual_call_template and specify the authentication
  • Another option would be to extend the manual_call_templates to have an auth field for the openapi itself, and another for the endpoints --> in this case the auth would always (actually not always, only where the OpenAPI specifies that an auth is required, roght?) be used to hit tools endpoints, also if half of the tools are open and the other half is protected. Example
  "manual_call_templates": [{
    "name": "github_api", 
    "call_template_type": "http",
    "url": "https://api.github.com/openapi.json",
    "auth": {
      "auth_type": "api_key",
      "api_key": "Bearer ghp_xxxxxxxxxxxx",
      "var_name": "Authorization",
      "location": "header"
    },
    "auth_tools": {
      "auth_type": "api_key",
      "api_key": "Bearer ghp_xxxxxxxxxxxx",
      "var_name": "Authorization",
      "location": "header"
    }  }]
}

Thinking a bit about it, maybe this could suffice:

  "manual_call_templates": [{
    "name": "github_api", 
    "call_template_type": "http",
    "url": "https://api.github.com/openapi.json",
    "auth": { // ← EXISTING SECTION, TO BE FILLED IF THE OPENAPI ENDPOINT IS PROTECTED 
      "auth_type": "api_key",
      "api_key": "Bearer ghp_xxxxxxxxxxxx",
      "var_name": "Authorization",
      "location": "header"
    },
    "auth_tools": {  // ← NEW SECTION BEING PROPOSED, TO BE FILLED IF THE TOOLS ENDPOINT ARE PROTECTED, AND TO BE APPLIED ONLY ON THE PROTECTED ENDPOINTS IN THE TRANSIENT UTCP MANUAL, AS PER SPECIFICATIONS IN THE OPENAPI FILE 
      "auth_type": "api_key",
      "api_key": "Bearer ghp_xxxxxxxxxxxx",
      "var_name": "Authorization",
      "location": "header"
    }  
  }]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants