# Authorization Methods Firstup supports three primary authorization methods to authenticate requests to our Partner API: * Client Credentials Grant * Authorization Code Grant * JWT Bearer Token Grant All methods are based on the OAuth 2.0 standard and require interaction with the Firstup authorization server: * US1 region: https://auth.socialchorus.com * US2 region: https://auth.us2.onfirstup.com * EU: https://auth.onfirstup.eu ## Client Credentials Grant This flow is best suited for server-to-server integrations that do not act on behalf of a specific user. **Use Cases** * System-level integrations. * Background jobs or automation tools. **Benefits** - Fast, simple authentication for trusted server apps. - No user login required. **Requirements** - Client ID and client secret. - No user interaction. **How it Works** When you don’t need to act on behalf of a user, you can use the Client Credentials grant to get an access token. This method uses just the Client ID and Client Secret, and gives the application the same permissions as a Program Manager. Contact [Firstup](https://support.firstup.io/hc/en-us) to get your `clientID` and `clientSecret`. It's ideal for endpoints like those in the [Content Publishing](/contentandpublishing/contentoverview) section. However, it won't work for endpoints that rely on a specific user, like those in the [Feeds](/feeds/feedsoverview) section, because it can't determine what content a user should see or track actions like likes and bookmarks. At a high level, use of this grant type will consist of: 1. Request access token 2. Use access token to make API calls 3. Repeat steps 1 and 2 as desired - Your backend system authenticates with Firstup using a client ID and secret. - An access token is issued that represents the system or application. ### Example This example uses the US1 region server: https://auth.socialchorus.com. Check your region's server [here](/authorization/authenticationandauthorization). Request format: ``` `curl -X POST \ https://auth.socialchorus.com/oauth/token \ -F grant_type=client_credentials \ -F client_id= \ -F client_secret=` ``` Sample request: ``` `curl -X POST \ https://auth.socialchorus.com/oauth/token \ -F grant_type=client_credentials \ -F client_id=fdf245738eb201e4ede5acff86d8552aa60c9afb30e45111ab9fa9054f31deb6 \ -F client_secret=cdef2738c0592f2daa516718f3be12d0d9ee2f9137832e333da7bdd105d43bd1` ``` Sample response: ``` `{ "access_token": "6fcb9647ace549e0208bb31dc581a4c4bc204032ab6694e73de77e611d77b23c", "token_type": "Bearer", "expires_in": 7200, "scope": "public", "created_at": 1539746984, "realm": "program:1" }` ``` ## Authorization Code Grant This method is for applications that require user interaction, such as web or mobile apps where a user logs in and authorizes access. This limits permissions of the api session to the permissions of the logged in user. **Use Cases** * Apps acting on behalf of a signed-in user. * Scenarios requiring user consent and identity verification. **Benefits** - Secure and widely adopted. - Suitable for scenarios requiring user login and consent. **Requirements** - Client ID and client secret. - Redirect URI registered with Firstup. - User login and consent. **How it Works** The Authorization Code grant flow produces the most versatile tokens because it associates the tokens with a user allowing the use of user-centric actions such as “like content item.” This flow breaks down as follows: 1. Sign in to the auth server 2. Give consent to the app 3. Request access token 4. Use access token to make API calls 5. Use refresh token to renew access token 6. Repeat steps 4 and 5 ### Example This example uses the US1 region server: https://auth.socialchorus.com. Check your region's server [here](/authorization/authenticationandauthorization). Using a web browser: Sign in, give consent, and retrieve your authorization token from: ``` `https://auth.socialchorus.com/oauth/authorize? client_id=& redirect_uri=https://auth.socialchorus.com/oauth/authorize/native& scope=openid%20public& state=& response_type=code` ``` Where `` is an arbitrary value that the client should create and check for in the response to ensure authenticity. Sample request: To request access to the API, contact [Firstup](https://support.firstup.io/hc/en-us). ``` `https://auth.socialchorus.com/oauth/authorize?client_id=c3aa8631a3c9bd72581cef94b13e2dc7c5d09e278adad1174b8f4e7749b81b3e& redirect_uri=https://auth.socialchorus.com/oauth/authorize/native& scope=openid%20public& state=mySUPER$3cRe7& response_type=code` ``` The page will look like this: ![authorization_code.png](#) If your app uses a different page for its redirect_uri, the authorization code can be found in the “code” query parameter of the URL you are redirected to after signing in and giving consent. Submit your token request in the form: ``` `curl -X POST \ https://auth.socialchorus.com/oauth/token \ -F grant_type=authorization_code \ -F redirect_uri=https://auth.socialchorus.com/oauth/authorize/native \ -F client_id= \ -F client_secret= \ -F code=` ``` Our [region servers](/authorization/authenticationandauthorization) use cookies to streamline the login process. If you are having trouble logging in, clear your cookies related to that site. Sample request: ``` `curl -X POST \ https://auth.socialchorus.com/oauth/token \ -F grant_type=authorization_code \ -F redirect_uri=https://auth.socialchorus.com/oauth/authorize/native \ -F client_id=fdf245738eb201e4ede5acff86d8552aa60c9afb30e45111ab9fa9054f31deb6 \ -F client_secret=cdef2738c0592f2daa516718f3be12d0d9ee2f9137832e333da7bdd105d43bd1 \ -F code=005c287916b62107a6ff04d970f5c4e996059cb31f820c83bc4bd0e39419437a` ``` Sample response: ``` `{ "access_token": "8ff789b389b3756f90d77c34fc3e2135964ccc4e3e7e6c4609e10fee5efc8dc5", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "ad1f9f4dc7d34385537e03f223873958571e54992ce10b83ac3b52f16b0e7c88", "scope": "openid public", "created_at": 1539732223, "id_token": "eyJ0eXAiOiJ...Aq3DxK23w", "realm": "program:1" }` ``` ### Authorization Code with PKCE PKCE (Proof Key for Code Exchange) is an extension to the Authorization Code grant flow designed to provide additional security for public clients, such as mobile apps or single-page applications (SPAs), which cannot securely store a `client_secret`. This method is effective at preventing authorization code interception attacks. **Benefits** * Enhanced security. * No client secret required. * Standards-compliant. * Widely supported. **Requirements** * Code Verifier: A high-entropy cryptographic random string (between 43 and 128 characters). * Code Challenge: A hashed version of the code verifier using SHA-256 (or plain text fallback, though SHA-256 is recommended). * PKCE Support in Your OAuth Server: The authorization server must support the code_challenge and code_verifier parameters (Firstup's auth server does support this). * Redirect URI: Your app must register and use a redirect URI to receive the authorization code after user authentication. * Browser or Web View Flow: Since PKCE requires user interaction, it’s typically used in apps with browser-based login flows. **How it Works** The Authorization Code with PKCE flow follows these general steps: 1. The client generates a code verifier (a high-entropy random string) and derives a code challenge from it. 2. The client initiates the authorization request with the code_challenge. 3. The user authenticates and grants permission. 4. The authorization server redirects back with an authorization code. 5. The client exchanges the code for an access token, passing the original code_verifier along with the request. 6. The authorization server verifies the code_verifier matches the previously provided code_challenge, and if valid, issues an access token. Refer to our full [PKCE flow example](/authorization/auth-code-grant-pkce) for more guidance. ### Refresh an access token Access Tokens expire after two hours. Once you receive your initial access token via authorization code, you can create subsequent tokens using the refresh grant. Access tokens produced by the refresh grant have the same rights and privileges as access tokens produced using the grant flow that produced the refresh token. Client Credentials grant does not provide a refresh token. When a Client Credentials grant access token expires, repeat the Client Credentials grant flow. The request is formatted as: This example uses the US1 region server: https://auth.socialchorus.com. Check your region's server [here](/authorization/authenticationandauthorization). `curl -X POST \ https://auth.socialchorus.com/oauth/token \ -F grant_type=refresh_token \ -F client_id= \ -F refresh_token=` Where the `refresh_token` from a previous authentication request. Sample request: ``` `curl -X POST \ https://auth.socialchorus.com/oauth/token \ -F grant_type=refresh_token \ -F client_id=fdf245738eb201e4ede5acff86d8552aa60c9afb30e45111ab9fa9054f31deb6 \ -F refresh_token=ad1f9f4dc7d34385537e03f223873958571e54992ce10b83ac3b52f16b0e7c88` ``` Sample response: ``` `{ "access_token": "f574ecddd18be52a2a6ed0485e8a6c47e5ef192b005fed400c90657b9b57cc7f", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "ef9ba00b28f270784cc34c1ad500ae2d112c95b214bed0172ea642a482671913", "scope": "openid public", "created_at": 1539616951, "id_token": "eyJ0eXAiOiJ...MvuurumUQ", "realm": "program:1" }` ``` ## JWT Bearer Token Grant This method is designed for clients that want to act on behalf of a specific user without an interactive login flow. It is well-suited for scenarios where clients have access to a secure private key and need to access user-specific APIs. Using JWTs, you can make authenticated calls to our user-specific APIs effortlessly and securely, bypassing the need for individual authorization codes. Always safeguard your private key and avoid exposure to unauthorized entities. **Use Case** * Scenarios where you need to exchange a signed JSON Web Token (JWT) for an access token. Often used for integrations involving identity federation, delegated access, or enterprize SSO. * JWT Bearer makes it possible to call the [Feeds API](/doorman/openapi/feeds) without triggering a user login prompt, enabling seamless integrations or automated content retrieval. * JWT Bearer authentication currently supports the Feeds operations. It is **not supported for SCIM** or other user-specific APIs that require live user authentication. **Benefits**: - Enables secure, stateless authentication. - Useful in federated identity or delegated scenarios. - Does not require client secret storage for each application. **Requirements**: * Pre-registered identity or service account with Firstup. * Signed JWT using a supported algorithm (typically RS256). HMAC (shared secret) signing is not supported. * You must share your **public key** with Firstup in advance so we can validate the JWT signature. * The `sub` (subject) claim should be a user identifier or email (notify Firstup which one). * The `iss` (issuer) and `aud` (audience) claims must be registered with Firstup. Ensure `aud` exactly matches what we’ve registered, or the request will be rejected. * Do not use JWT-based token exchange directly from a browser or frontend application. This flow is for server-side integrations only. ### How it Works **Step 1: Generate a Public/Private Key Pair** ``` # Generate a private key openssl genpkey -algorithm RSA -out private_key.pem # Generate a public key openssl rsa -pubout -in private_key.pem -out public_key.pem ``` **Step 2: Securely Store the Private Key** Ensure the `private_key.pem` is stored securely, and access is limited to authorized entities. **Step 3: Share the Public Key with Firstup** Send Firstup the public_key.pem, which we'll use to validate JWTs signed with your private key. **Step 4: Use the Private Key to Sign JWT Tokens** Utilize a JWT library to sign tokens with your private key. This example employs Node.js and the `jsonwebtoken` library. **Understanding JWT Claims** As noted in the *requirement* section: * `iss`: The issuer claim. Identifies who issued the JWT. Send this arbitrary string to us for setup on our end. * `aud`: The audience claim. Specifies intended recipients (Firstup). Send this string to us for setup on our end. Adjust this to your region. * `exp`: The expiration time claim. States when the token will expire. * `sub`: The subject claim. Represents the user being claimed using their email or universal identifier (notify Firstup which one). The subject claim (`sub`) **must be in string format** in the payload ``` { "iss": "needs-to-match-your-jwt-issuer", "sub": "unique-identifier-of-user-we-want-to-impersonate", "exp": 1754079156, //replace with UNIX timestamp of expiration date "aud": "https://auth.socialchorus.com/oauth/token" } ``` **Step 5: Send the JWT to Firstup for Token Exchange** ``` const axios = require('axios'); // The JWT token you've generated const YOUR_JWT_TOKEN = 'YOUR_JWT_TOKEN'; // The CLIENT_ID provided by Firstup const YOUR_CLIENT_ID = 'YOUR_CLIENT_ID'; // Define the AUTH_URL based on the region (US or EU) const AUTH_URL_US = 'https://auth.socialchorus.com/oauth/token'; const AUTH_URL_EU = 'https://auth.onfirstup.eu/oauth/token'; axios.post(AUTH_URL_US, null, { params: { grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', client_id: YOUR_CLIENT_ID, assertion: YOUR_JWT_TOKEN }, }) .then(response => { const accessToken = response.data.access_token; console.log(`Received access token: ${accessToken}`); }) .catch(error => { console.error(`Error during token exchange: ${error}`); }); ``` **Step 6: Use the Access Token in the Header for API Calls** Once you have the access token, you can include it in the Authorization header to authenticate your API calls. Typically, the token is prefixed with the word "Bearer". **Endpoint References** * US1: https://partner.socialchorus.com/v2/Feed/... * US2: https://partner.us2.onfirstup.com/v2/Feed/... * EU: https://partner.onfirstup.eu/v2/Feed/... **Example of Making a Call Using the Access Token with the `axios` Library in `node.js`:** ``` const axios = require('axios'); // The access token you've received from the token exchange const accessToken = 'YOUR_RECEIVED_ACCESS_TOKEN'; // Define the API_URL based on the region (US or EU) const API_URL_US = 'https://partner.socialchorus.com/v2/feed/...'; const API_URL_EU = 'https://partner.onfirstup.eu/v2/feed/...'; axios.get(API_URL, { headers: { 'Authorization': `Bearer ${accessToken}` } }) .then(response => { console.log('API response:', response.data); }) .catch(error => { console.error('Error calling the API:', error); }); ``` By including the bearer token in the header, the API knows the request comes from an authenticated source, granting access for a specific user. Ensure your access token is kept confidential and is not exposed to unauthorized parties. **Sample Code** ``` const fs = require('fs'); const jwt = require('jsonwebtoken'); // Load your private key const privateKey = fs.readFileSync('private_key.pem', 'utf8'); // Define your payload (the claims of the JWT) const payload = { iss: 'your-identifier', aud: 'our-identifier', exp: Math.floor(Date.now() / 1000) + (60 * 60), sub: 'user_id_you_want_to_claim' // email on file, federated ID or advocate ID }; // Sign the JWT const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' }); console.log(token); ``` ## Choosing the Right Method | Use Case | Recommended Method | | --- | --- | | Mobile or browser-based app | Authorization Code Grant with PKCE | | App that needs to act on user’s behalf | Authorization Code Grant | | Backend system or automated process | Client Credentials Grant | | Identity delegation or SSO integrations | JWT Bearer Token Grant | If you're unsure which method fits your use case, please contact your Firstup representative for assistance.