# Authorization Backend: Video Access Control by Your System's Rules


Kinescope lets you control video access through an external authorization backend. This means you decide who can watch a specific video — based on your system's rules (courses, subscriptions, roles, etc.).

## Who this article is for

* **LMS developers** — need to control video access by course and lesson
* **Subscription platform owners** — need to restrict access based on subscription status
* **Corporate system administrators** — need to configure access by role and group
* **Backend developers** — need to integrate an access control system with Kinescope

## When you need an authorization backend

Here are typical situations where this is useful:

- **Access to part of the media library**: a user purchased a course or package but doesn't have access to the entire library.
- **Subscription**: videos are only accessible while the subscription is active (or the trial period hasn't expired).
- **Individual lesson purchases**: access only to specific videos the user paid for.
- **Corporate access**: access by organizational role (employees, partners) or group membership.
- **Contextual restrictions**: access by IP, geolocation, time window, device, or session.

If at least one of these scenarios applies to you — read on. Below is how to set up access checking in two steps.

## **How access checking works (4 steps)**

1. You pass a user identifier to the Kinescope player.
2. When a user tries to watch a video, Kinescope asks your backend: "Can this user watch this video?"
3. Your backend checks the rules (course, subscription, role, etc.) and responds: **200** (allow) or **403** (deny).
4. The player opens or blocks access.

Now let's walk through how to set this up.

## **Setup: step 1 — passing a user identifier**

When embedding the player on a website, pass the authorization token via the `drmauthtoken` parameter in the URL:

```markup
<iframe
  src="https://kinescope.io/embed/pcFNnQGsD59CMKte2SQQaz?drmauthtoken=${user_id}"
  width="640"
  height="360"
  frameborder="0"
  allow="autoplay; fullscreen; picture-in-picture; encrypted-media;"
></iframe>
```

You can use any string as a token: `user_id`, a JWT token, or another identifier your backend can verify.

> **Recommendation (security):** For production, we recommend using a **signed JWT** in `drmauthtoken`. This protects against token substitution on the client. On the backend, validate the JWT signature and extract the `user_id`.
>
> **For developers:** When validating a JWT, check the standard fields: `exp` (expiration), `aud` (audience), `iss` (issuer) — this improves security.

## **Setup: step 2 — connecting your backend**

For Kinescope to be able to call your backend to check access, add your endpoint's URL to the project or workspace settings via the Kinescope API.

> **Important:** The API token in the `Authorization: Bearer` header must be in UUID format. You can get a token from the [Kinescope Dashboard](https://app.kinescope.io) in **Settings → API tokens**. Learn more about authorization and error handling in the [general API guidelines](https://docs.kinescope.com/developer-guides/api-general-rules/).

DRM can be configured at two levels:
- **Workspace** — applies to all projects
- **Project** — applies to a specific project (overrides workspace settings)

**Setting up the authorization backend URL via API:**

**For the entire workspace:**

```bash
curl -X PUT "https://api.kinescope.io/v1/drm/auth" \
  -H "Authorization: Bearer ${KINESCOPE_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.example.com/drm/authorize",
    "username": "drm_user",
    "password": "drm_password",
    "strict": false
}'
```

**For a specific project:**

```bash
curl -X PUT "https://api.kinescope.io/v1/drm/auth/${PROJECT_ID}" \
  -H "Authorization: Bearer ${KINESCOPE_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.example.com/drm/authorize",
    "username": "drm_user",
    "password": "drm_password",
    "strict": false
}'
```

**Request parameters:**
- `url` (required) — URL of your access check endpoint (where Kinescope will send requests during playback)
- `username` (optional) — username for Basic Auth to your service
- `password` (optional) — password for Basic Auth
- `strict` (optional) — strict checking mode

**Checking current settings:**

```bash
# For workspace
curl -X GET "https://api.kinescope.io/v1/drm/auth" \
  -H "Authorization: Bearer ${KINESCOPE_API_TOKEN}"

# For project
curl -X GET "https://api.kinescope.io/v1/drm/auth/${PROJECT_ID}" \
  -H "Authorization: Bearer ${KINESCOPE_API_TOKEN}"
```

> **Important:** Kinescope sends an HTTP request with JSON to your URL (see example below). In response, simply return **200** (allow) or **403** (deny).

## **What arrives at your backend**

When a user tries to watch a video, Kinescope sends JSON with context to your authorization URL:

```json
{
  "id": "7127f2d7-0e96-40d0-9a03-2e987c096466",
  "ip": "11.22.33.0",
  "type": "video",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ..."
}
```

**Field descriptions:**
- `id` — ID of the video being accessed
- `token` — authorization token you passed in `drmauthtoken` (e.g., `user_id` or JWT)
- `ip` — user's IP address
- `type` — content type (usually `"video"`)
- `user_agent` — user's browser User-Agent

## **What to return in response**

Your backend must return one of these HTTP codes:

| Code | When to use | What happens next |
|---|---|---|
| **200 OK** | User **has the right** to watch the video | Kinescope issues the decryption key, the player starts playback |
| **403 Forbidden** | User **does not have the right** to watch the video | Access is blocked, video does not play |
| **400 Bad Request** | Invalid JSON or missing required fields | Integration error (check request format) |
| **5xx** | Temporary error on your side | Kinescope cannot obtain access confirmation |

> **For developers:** If your backend is temporarily unavailable (5xx), Kinescope won't be able to check access. We recommend setting up monitoring and quick service recovery.

## **How to check access (minimal scheme)**

Here's what you need to do in your authorization handler:

1. **Extract `user_id` from `token`**: if you use JWT — validate the signature and extract `user_id`; if you pass `user_id` directly — just use it.
2. **Identify the video context**: by `id` (video ID), determine which course/package/section the video belongs to.
3. **Check permissions in your system**: does the user have access (purchase, subscription, role, group, etc.).
4. **Return a response**: **200** if access is granted, otherwise **403**.

Briefly in pseudocode:

```text
user_id = verify_and_extract_user_id(token)
if user_id is empty -> 403

if user_has_access_to_video(user_id, video_id) -> 200
else -> 403
```

## **Example: access only to a purchased course**

Say your site has courses and a user bought only one of them. How do you check access to a video in that course?

**Step 1:** Map videos to courses in your system (e.g., a `course_videos` table with `course_id` and `video_id` fields).

**Step 2:** In your authorization handler:
- Extract `user_id` from `token` (validate JWT if you use it).
- Find `course_id` by `video_id`.
- Verify the user is enrolled in the course, has paid, and the course is active.
- Return **200** if all checks pass, otherwise **403**.

Pseudocode:

```text
course_id = find_course_by_video(video_id)
if course_id is empty -> 403

if enrollment_is_active(user_id, course_id) -> 200
else -> 403
```

## **How it works (in detail)**

Here's what happens when a user opens a page with the player:

1. **User opens the page** — your site passes the authorization token (e.g., `user_id` or JWT) to the Kinescope player via the `drmauthtoken` parameter.
2. **Kinescope calls your backend** — sends an HTTP request with JSON containing:
   - the authorization token (the one you passed in `drmauthtoken`);
   - the video ID;
   - the user's IP address and User-Agent.
3. **Your backend checks access** — reviews the rules in your system (course, subscription, role, etc.) and returns a response:
   - **HTTP 200** — access granted, the license server issues a decryption key, video becomes available.
   - **HTTP 403** — access denied, video does not play.
4. **The player receives the response** — opens or blocks video access.

Done! Now you can control video access using any rules from your system.

## What's next?

After setting up the authorization backend, we recommend:

1. **[DRM file encryption](https://docs.kinescope.com/content-protection/drm-encryption/)** — additional content protection
2. **[Video access restrictions](https://docs.kinescope.com/content-protection/access-restrictions/)** — other ways to restrict access
3. **[General API guidelines](https://docs.kinescope.com/developer-guides/api-general-rules/)** — authorization and request format

Still have questions? Write to the support chat within the Kinescope interface — our specialists will help!

