Skip to content

LIVE app receives direct HTTP 403 during OAuth authorization-code token exchange #411

Description

@baardstream

Describe the bug

A LIVE Kick developer application successfully reaches the user consent screen and receives an authorization code, but the subsequent token exchange is rejected directly by https://id.kick.com/oauth/token with HTTP 403.

Application:

  • Name: NovaDesktop
  • Client ID: 01M0SXZC8SA1KM4F005841FTEY
  • Portal status: LIVE
  • Redirect URI: http://localhost:48192/callback
  • Scopes: user:read channel:read
  • Latest controlled attempt: 2026-08-29T14:15:32.642809Z

The Client Secret was rotated once in the Kick portal and saved into the application's protected credential store before one fresh authorization attempt. The rejection remained unchanged.

To reproduce

  1. Configure the LIVE application with the redirect URI and scopes shown above.
  2. Start an OAuth 2.1 authorization-code flow with S256 PKCE and a fresh state value.
  3. Approve access on the Kick consent screen.
  4. Exchange the returned code once at POST https://id.kick.com/oauth/token.
  5. Observe HTTP 403.

No replay or second attempt was performed.

Expected behavior

The documented form-encoded token request should return a user access token response, or a documented OAuth error that identifies the invalid request condition.

Safe diagnostics

status=error
callback_status=rejected
policy=deny
completion_phase=provider_http_response
completion_reason=KICK_TOKEN_HTTP_REJECTED
provider_http_status=403
token_transport_route=direct
token_destination_host=id.kick.com
token_response_host=id.kick.com
token_redirect_count=0
token_proxy_bypassed=false
token_tls_termination=direct
provider_response_origin=kick

Offline request-conformance audit

The request was intercepted locally before network transport and verified to use:

  • POST https://id.kick.com/oauth/token
  • Content-Type: application/x-www-form-urlencoded
  • exactly one each of grant_type, client_id, client_secret, code, redirect_uri, and code_verifier
  • grant_type=authorization_code
  • the exact registered redirect URI
  • the matching PKCE verifier
  • correct form encoding, including reserved characters
  • no JSON body, nonce, duplicate field, or Authorization header

The transport was direct to id.kick.com, with zero redirects. The Python HTTP stack uses its standard non-browser User-Agent; the Kick documentation does not state that a browser-like User-Agent is required.

Environment

  • Local Windows desktop application
  • NovaDesktop v2.0.0-rc4
  • OAuth transport: Python standard-library HTTPS client
  • Browser authorization: Chrome

Request for Kick Engineering

Could you please confirm:

  1. Whether user-token exchange is enabled internally for this application.
  2. Whether the application or owner account is subject to an unverified-app, trust, regional, WAF, or account-level restriction.
  3. Whether the LIVE state and configured scopes are correctly propagated to the OAuth backend.
  4. Whether the application requires manual reprovisioning.
  5. Whether non-browser HTTP User-Agents are restricted at id.kick.com.

No Client Secret, authorization code, PKCE verifier, token, callback query, cookie, screenshot, email address, or raw provider response body is included in this report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions