← Back to appMCA Manager Helpmcamgr.com
Browse help topics

Connected apps (OAuth 2.0)

A connected app is an integration that authenticates with OAuth 2.0 instead of a fixed API key. It trades its client id and secret for an access token that lasts one hour, and the REST API accepts that token wherever it accepts a key. Each company is its own OAuth server: the issuer is your company address, e.g. https://acme.mcamgr.com, with metadata at /.well-known/oauth-authorization-server.

Manage apps under Settings → Connected apps: the same permissions as API keys (edit company settings to see and revoke; API access as well to add apps and issue secrets), and an app can never be given more than the person adding it could do on screen.

Two kinds of app

KindForFlow
ServiceA back-office job that acts as itself — a nightly sync, an accounting export.Client credentials
Acts for a userA tool your staff sign in to, which works as them.Authorization code + PKCE

Service apps: client credentials

curl -u mca_client_…:mca_cs_… -d grant_type=client_credentials \
  https://acme.mcamgr.com/oauth/token
→ { "access_token": "mca_at_…", "token_type": "Bearer", "expires_in": 3600, "scope": "deals:read payments:read" }

The client may also send client_id and client_secret in the form body. scope= (space-separated) asks for fewer scopes than the app has; leave it out for all of them. Reuse a token until it expires — an app asking for a new one on every call is throttled.

Apps that act for a user: authorization code + PKCE

  1. Register the app's return addresses (redirect URIs). They must be https (http only for localhost) and are matched exactly.

  2. Send the person to

    https://acme.mcamgr.com/oauth/authorize?response_type=code&client_id=mca_client_…
      &redirect_uri=https://app.example.com/callback&scope=deals:write%20payments:read
      &state=<random>&code_challenge=<BASE64URL(SHA256(verifier))>&code_challenge_method=S256
    

    They sign in if needed and see what the app asks for. Anything beyond their own permissions is shown and left out (a write they lack becomes read when they hold it). Allow returns them to your address with ?code=…&state=…; Deny with ?error=access_denied.

  3. Within 60 seconds, exchange the code:

    curl -u mca_client_…:mca_cs_… https://acme.mcamgr.com/oauth/token \
      -d grant_type=authorization_code -d code=… -d code_verifier=… \
      -d redirect_uri=https://app.example.com/callback
    → { "access_token": "mca_at_…", "refresh_token": "mca_rt_…", "expires_in": 3600, "scope": "deals:write" }
    
  4. When the access token expires, grant_type=refresh_token&refresh_token=mca_rt_… returns a new pair. Refresh tokens rotate: use the new one next time. A refresh token or code used twice is treated as stolen and every token of that authorization is revoked. Refresh tokens last 30 days.

Every call made with such a token is checked against the person as they are now: lose a permission and the app loses it too; be deactivated and its tokens stop working. Funding, payment and refund rules apply exactly as for that person on screen, and the audit trail names them.

Secrets, revoking, the trail

  • The client secret is shown once. New secret issues another and keeps the old one working for 24 hours.
  • Revoke stops the app and every token it holds, at once.
  • For an app that acts for users, the list shows who has authorized it. Anyone can withdraw their own authorization; edit company settings can withdraw anyone's.
  • Narrowing an app's scopes applies to tokens already issued.
  • POST /oauth/revoke (RFC 7009) lets the app revoke its own token; revoking a refresh token takes its access tokens with it. POST /oauth/introspect (RFC 7662) tells it whether one of its tokens is still live.
  • Every app change, token issued and token revoked is in the audit log, and API calls appear in the request log like a key's.

Can’t find what you need? Return to the app or contact your administrator.

Connected apps (OAuth) - Help