OAuth 2.0 Integration with Tempo Timesheets API in Forge (Rovo Agent) - "Bad provider or missing config" Error

Hi there!

I’m trying to integrate OAuth 2.0 authentication with Tempo Timesheets API in my Forge app (is a Rovo Agent that connects to Tempo Timesheets), but I’m getting a persistent error and would appreciate guidance as this is the first time I code a Rovo agent.

Current error:

:cross_mark: Tempo OAuth authentication failed:
Error: Bad provider or missing config for provider tempo
at findExternalAuthProviderConfigOrThrow (webpack://tempo-analysis-agent/node_modules/@forge/api/out/api/fetch.js:70:1)
at buildExternalAuthAccountsInfo (webpack://tempo-analysis-agent/node_modules/@forge/api/out/api/fetch.js:110:24)
at withProvider (webpack://tempo-analysis-agent/node_modules/@forge/api/out/api/fetch.js:138:1)

My setup:

Tempo OAuth App Configuration:

  • Client ID: created in Tempo
  • Redirect URI: https://my-site.atlassian.net/outboundAuth/finish

Forge Environment Variables:

forge variables list
├── TEMPO_CLIENT_ID (encrypted): ****
└── TEMPO_CLIENT_SECRET (encrypted): ****

manifest.yml:

providers:
  auth:
    - key: tempo
      name: Tempo Timesheets
      type: oauth2
      clientId: TEMPO_CLIENT_ID
      scopes:
        - read:worklogs:jira
        - read:timesheets:jira
      remotes:
        - tempo-api
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: tempo-api
          path: /oauth/authorize
        exchange:
          remote: tempo-api
          path: /oauth/token
        revokeToken:
          remote: tempo-api
          path: /oauth/revoke
        retrieveProfile:
          remote: tempo-api
          path: /me
          resolvers:
            id: accountId
            displayName: displayName
            avatarUrl: avatarUrl

remotes:
  - key: tempo-api
    baseUrl: https://api.eu.tempo.io

function:
  - key: analyzeTempoData
    handler: index.analyzeTempoData
    providers:
      - tempo

permissions:
  external:
    fetch:
      backend:
        - https://api.eu.tempo.io

index.js:

async function getTempoClient() {
  const tempo = api.asUser().withProvider("tempo", "tempo-api");
  
  if (!(await tempo.hasCredentials())) {
    await tempo.requestCredentials();
  }
  
  return tempo;
}

// Usage in function
const tempoClient = await getTempoClient(); // ❌ Fails here

What I tried:

  • Configured environment variables with forge variables set --encrypt
  • Configured provider with forge providers configure tempo
  • Validated manifest with forge lint (no errors)
  • Tried different endpoint configurations (auth.eu.tempo.io vs api.eu.tempo.io)
  • Verified Tempo OAuth app configuration in Tempo

My questions:

  1. Is Tempo Timesheets API officially supported by Forge OAuth providers? I couldn’t find any documentation or examples of this integration.
  2. Are the OAuth endpoints correct?
  3. Could the redirect URI format be the issue?
  4. Should I use a different approach? Would it be better to implement OAuth in a separate service and call it from Forge?