JWT Authorization

Overview

This document provides an overview of JSON Web Tokens (JWT) and a step-by-step guide to authorizing a Kiteworks API client using the OAuth JWT Assertion Flow, referencing a provided Python source code sample.

Introduction to JSON Web Tokens (JWT)

A JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs are widely used for authentication and authorization in modern web applications, offering a stateless and scalable approach compared to traditional session-based methods.

A JWT typically consists of three parts, separated by dots (.), each Base64Url encoded:

  • Header: This part usually contains two fields: typ (type of token, which is JWT) and alg (the signing algorithm used, e.g., HS256 for HMAC SHA256 or RS256 for RSA SHA256).

  • Payload: Also known as the "claims set," the payload carries statements about an entity (typically the user) and additional data. Claims can be:

    • Registered Claims: Predefined claims like iss (issuer), sub (subject), aud (audience), exp (expiration time), iat (issued at), and nbf (not before). These are not mandatory but are recommended.

    • Public Claims: Custom claims defined by users, such as user role or ID.

    • Private Claims: Custom claims created to share information between parties that agree on using them.

  • Signature: This crucial part is created by encoding the header and payload with a secret key (for symmetric algorithms like HS256) or a public/private key pair (for asymmetric algorithms like RS256) using the algorithm specified in the header. The signature ensures the integrity and authenticity of the token, preventing tampering and verifying the sender.

The key benefits of JWTs include their stateless nature, compactness, and security when implemented correctly. They are ideal for distributed systems, microservices, and mobile applications where scaling and cross-domain compatibility are important.

Create a Custom Application in Kiteworks

Before implementing the JWT flow, the application must be registered on the Kiteworks server by an administrator.

  1. Create a custom application: Navigate to Application Setup > Apps and Plugins > API in the admin interface. Click "Create Custom Application" and specify the name, description, and required authorization flow.

  2. Configure JWT-specific details: For JWT authorization flow, the following information needs to be configured:

    • Subject (UID Attribute): Attribute in JWT indicating the user email address.

    • Issuer: This must match the iss (issuer) attribute of the JWT.

    • Audience: This must match the aud (audience) attribute of the JWT. It can be the URL of the Kiteworks machine or any ID specified by the JWT issuer.

    • Algorithm: The JWT signing algorithm (e.g., RS256) that will be used for signing the JWT.

    • Public Key: The public key corresponding to the private key used to sign the JWT, which Kiteworks will use to verify the JWT signature.

  3. Select scopes to define access to data: Define the set of allowed API endpoints for the application by selecting the appropriate scopes. This reduces potential security risks by limiting data exposure.

  4. Provide authorization credentials to your developer: Copy the Client Application ID and Client Secret Key to a secure location. These credentials must be securely accessible by developers for use in gaining authorization to Kiteworks Secure APIs.

  5. Test the custom application: Use authentication samples from the Secure API Playground, along with the Client ID and Client Secret, to retrieve an access token and test additional API endpoints as needed.

Authorize a Kiteworks API Client using JWT

The OAuth JWT Assertion Flow in Kiteworks allows a registered client to use its credentials (client_id and client_secret) along with a valid JWT assertion to obtain an access token.

Step 1: Generate a JWT Token

The client application is responsible for creating and signing the JWT assertion. The JWT must include specific claims in its payload:

  • iss (Issuer)

  • aud (Audience)

  • sub (Subject, e.g., the Kiteworks user's email)

  • iat (Issued At timestamp)

  • nbf (Not Before timestamp)

  • exp (Expiration Time timestamp – usually set for a short duration, e.g., 5 minutes or 300 seconds)

  • jti (JWT ID – a unique identifier to prevent replay attacks)

The header typically specifies {"alg": "RS256", "typ": "JWT"}. The JWT is then signed using a private key (e.g., RSA private key) corresponding to a public key uploaded to the Kiteworks server. The provided jwt_assertion.py source code sample demonstrates this process within the create_jwt_assertion method, which builds the JWT payload and signs it.

Step 2: Request an Access Token

Once the JWT assertion is generated, the client sends an HTTP POST request to the Kiteworks token endpoint (https://kiteworks_server/oauth/token) with the following parameters:

  • client_id: The ID of the client application.

  • client_secret: The client application's secret phrase.

  • grant_type: Must be urn:ietf:params:oauth:grant-type:jwt-bearer.

  • assertion: The complete signed JWT token.

  • scope (Optional): The API services the client application wants to access (e.g., */files/* */folders/*). This must be a subset of the client's registered scopes.

  • install_tag_id (Optional): A string to uniquely identify the device.

  • install_name (Optional): A friendly name for the device.

 

Example POST request:

Copy
POST /oauth/token HTTP/1.1 Host: kiteworks_server Content-type: application/x-www-form-urlencoded client_id=playground&client_secret=secret&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-ty&assertion=eyJhbGci[...]

Successful Response

If the credentials and JWT assertion are valid, the server returns an HTTP 200 OK response with a JSON payload containing:

  • access_token: The token to use for subsequent API requests.

  • expires_in: The lifetime of the access token in seconds.

  • scope: The scopes for which the token is valid.

  • token_type: Set to "bearer".

 

Example successful response:

Copy
HTTP/1.1 200 OK Cache-Control: no-store Content-Type: application/json {"access_token":"054915e674bc35fa7fff1f499044e964d3a5d61b","expires_in":3600,"token_type":"bearer"}

When the access token expires, a new valid JWT assertion must be generated to request another access token.

Source Code Sample Reference

The jwt_assertion.py script provides a practical demonstration of how to implement the client-side logic for the OAuth JWT Assertion Flow.

The script defines an OAuthJWTAssertionClient class with the following key methods:

  • __init__: Initializes the client with necessary parameters such as the JWT issuer, subject, audience, the RSA private_key for signing, the token_endpoint URL, client_id, client_secret, and the signing algorithm (defaulting to "RS256").

  • create_jwt_assertion(self, validity_seconds=300): This method constructs the JWT payload with claims like iss, sub, aud, iat, nbf, exp, and jti. It then signs this payload using the provided RSA private key and the specified algorithm, returning the Base64Url encoded JWT assertion string.

  • get_access_token(self, scope=None, validity_seconds=300): This method orchestrates the access token request. It first calls create_jwt_assertion to get a signed JWT. Then, it prepares the POST data, including client_id, client_secret, grant_type (urn:ietf:params:oauth:grant-type:jwt-bearer), and the assertion. Finally, it sends the request to the token_endpoint and parses the JSON response to extract and return the access_token.

 

The if __name__ == "__main__": block at the end of the script demonstrates how to use the OAuthJWTAssertionClient. It prompts the user for inputs like the Kiteworks instance domain, private key file path, username, JWT audience, client ID, and client secret, then uses these to obtain and print an access token. This script encapsulates the process of generating a signed JWT and exchanging it for an OAuth 2.0 access token, making it a valuable reference for developers integrating with Kiteworks using this flow.