Choosing authentication type for JWT credential in connection builder

Summary

When using the connection builder with a JWT credential, ensure you select the correct authentication type to avoid API error code 401.


Question

When using the connection builder, which type of authentication should I be choosing if I have a JWT credential to pass? I have a valid, working credential that has been tested in some boilerplate python, but the connection builder is getting an API error code of 401 with the message OAuth token is invalid



This topic has been created from a Slack thread to give it more visibility.
It will be on Read-Only mode here. Click here if you want
to access the original thread.

Join the conversation on Slack

["authentication-type", "JWT-credential", "connection-builder", "API-error-401", "OAuth-token"]

It might be not supported in the connection builder yet (I checked Airbyte 0.63.16, not the latest version)

Low-Code CDK has <airbyte/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/jwt.py at 7db4145e543714ad87f95a4082e0914eb8c4e0d0 · airbytehq/airbyte · GitHub class>, so there is a high chance that at some point it will be implemented in connection builder as well.

According to the <https://docs.airbyte.com/release_notes/april_2024|release notes>, it should be available. Is this for OSS only?

> Added support for JWT authentication in the low-code CDK, which opens up access to connectors that require this type of authentication.
I consider Connector Builder as some kind of wrapper for low-code CDK. Sometimes you cannot configure all the things with user interface that is possible with YAML

I’ve tried switching to the YAML editor and when I tried to switch to the JwtAuthenticator, I get an error message

  File "/home/airbyte/.pyenv/versions/3.10.14/lib/python3.10/site-packages/airbyte_cdk/sources/declarative/manifest_declarative_source.py", line 192, in _validate_source
    validate(self._source_config, declarative_component_schema)
  File "/home/airbyte/.pyenv/versions/3.10.14/lib/python3.10/site-packages/jsonschema/validators.py", line 934, in validate
    raise error
jsonschema.exceptions.ValidationError: 'JwtAuthenticator' is not one of ['ApiKeyAuthenticator']```

Can you provide YAML?

I have updated the YAML, I believe the configuration was incomplete for the authenticator block… but I am receiving a new error:
OAuth token is invalid
Is this because the word “Bearer” is being included inside the JWT string? My full YAML is attached


  type: DeclarativeSource

  check:
    type: CheckStream
    stream_names:
      - Call Logs

  definitions:
    streams:
      Call Logs:
        type: DeclarativeStream
        name: Call Logs
        retriever:
          type: SimpleRetriever
          requester:
            $ref: "#/definitions/base_requester"
            path: /restapi/v1.0/account/~/call-log
            http_method: GET
            request_parameters:
              view: Detailed
            request_headers:
              accept: application/json
          record_selector:
            type: RecordSelector
            extractor:
              type: DpathExtractor
              field_path: []
        schema_loader:
          type: InlineSchemaLoader
          schema:
            $ref: "#/schemas/Call Logs"
    base_requester:
      type: HttpRequester
      url_base: <https://platform.ringcentral.com>
      authenticator:
        type: JwtAuthenticator
        api_token: "{{ config['api_token'] }}"
        algorithm: HS256
        secret_key: "{{ config['client_secret'] }}"
        header_prefix: Bearer

  streams:
    - $ref: "#/definitions/streams/Call Logs"

  spec:
    type: Spec
    connection_specification:
      type: object
      $schema: <http://json-schema.org/draft-07/schema#>
      required:
        - client_id
        - client_secret
        - api_key
      properties:
        client_id:
          type: string
          order: 0
          title: Client ID
        client_secret:
          type: string
          order: 1
          title: Client Secret
        api_key:
          type: string
          order: 2
          title: API Key
          airbyte_secret: true
      additionalProperties: true

  metadata:
    autoImportSchema:
      Call Logs: true
    yamlComponents:
      global:
        - authenticator
    testedStreams:
      Call Logs:
        hasRecords: false
        streamHash: daebf45b8bc248a8d8118571eb639e68bf39c3a2
        hasResponse: true
        primaryKeysAreUnique: true
        primaryKeysArePresent: true
        responsesAreSuccessful: false
    assist: {}

  schemas:
    Call Logs:
      type: object
      $schema: <http://json-schema.org/schema#>
      additionalProperties: true
      properties:
        navigation:
          type:
            - object
            - "null"
          properties:
            firstPage:
              type:
                - object
                - "null"
              properties:
                uri:
                  type:
                    - string
                    - "null"
        paging:
          type:
            - object
            - "null"
          properties:
            page:
              type:
                - number
                - "null"
            perPage:
              type:
                - number
                - "null"
        records:
          type:
            - array
            - "null"
        uri:
          type:
            - string
            - "null"```

I checked https://github.com/airbytehq/airbyte/blob/66b49214ff2d82755879b14278e37b8531f1a738/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml#L853-L973|declarative_component_schema.yaml#L853-L973
header_prefix: Bearer seems to be fine according to specification

I’m not sure about api_token in your YAML

      type: HttpRequester
      url_base: <https://platform.ringcentral.com>
      authenticator:
        type: JwtAuthenticator
        api_token: "{{ config['api_token'] }}"
        algorithm: HS256
        secret_key: "{{ config['client_secret'] }}"
        header_prefix: Bearer```

I added that in order to try to get some control over how the JWT is passed… leaving it out throws the same error. It’s called api_token because I started this in the UI and that is the default name for the user config input.

I checked RingCentral docs and code
https://developers.ringcentral.com/guide/authentication/jwt/quick-start
https://github.com/ringcentral/ringcentral-python/blob/a61e8739051b90de0e8585c0269d59029b9d0fb1/ringcentral/platform/platform.py#L189-L191|platform.py#L189-L191

Good luck with reverse engineering how to call that API to make it work.
I’d rather use Python CDK and their library than learn intricacies of YAML and JWT flow on RingCentral :wink: