Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Iblai Api Studio Auth

ASecurity

Sign in to Open edX Studio (studio.learn.iblai.app) and the LMS from a browser window the user controls, capture the session cookies (studio_session_id, sessionid, csrftoken) with the bundled Playwright script, verify them, and write the gitignored studio.env that every /iblai-api-studio-* skill reads; --check validates an existing session in one command. Use first whenever the user wants to author or configure an Open edX course from the terminal, and again when a Studio call answers 302 to ...

15 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentpythongoshellbashnodedjangogitapi

Works with

terminalapi

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add iblai/vibe --skill iblai-api-studio-auth --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Iblai Api Studio Auth?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Iblai Api Studio Auth
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iblai-iblai-api-studio-auth/badge)](https://www.skillsdirectory.com/skills/iblai-iblai-api-studio-auth)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: iblai-api-studio-auth
description: Sign in to Open edX Studio (studio.learn.iblai.app) and the LMS from a browser window the user controls, capture the session cookies (studio_session_id, sessionid, csrftoken) with the bundled Playwright script, verify them, and write the gitignored studio.env that every /iblai-api-studio-* skill reads; --check validates an existing session in one command. Use first whenever the user wants to author or configure an Open edX course from the terminal, and again when a Studio call answers 302 to /login, 403 CSRF, or an HTML "Studio Server Error" page. Session auth only — no Api-Token, no password handling. For the build order and the other Studio skills, see /iblai-api-studio.
metadata:
  kind: api
---

# iblai-api-studio-auth

Studio (the Open edX CMS) has no token API for authoring: every authoring
endpoint is guarded by a **Django session cookie + CSRF token**. This skill
captures that session from a browser the user signs into, verifies it against
Studio **and** the LMS (the LMS side shares the same login), and stores it
in `studio.env`. Run it once per host; sessions last about two weeks.

## Preflight — run this before any other Studio skill

```bash
node .claude/skills/iblai-api-studio-auth/scripts/studio-login.mjs --check && grep -q '^STUDIO_ORG=.\+' studio.env && echo "STUDIO_ORG set" || echo "MISSING: run /iblai-api-studio-auth and set STUDIO_ORG in studio.env"
```

`--check` prints `studio: ok · lms: ok` and exits 0 when both sessions work,
exits 2 when the file is missing or a session expired. Every other
`/iblai-api-studio-*` skill starts with this line; when it fails, come back
here instead of retrying calls.

## What gets written

| Key | Value | Used by |
|---|---|---|
| `STUDIO_URL` | `https://studio.learn.iblai.app` (default) — test server `https://studio.learn.iblai.org` | every `/iblai-api-studio-*` skill |
| `LMS_URL` | `https://learn.iblai.app` (derived: strip `studio.`) | `/iblai-api-studio-lms`, verification links |
| `LMS_APP_URL` | `https://lms.ibl.ai` (test: `https://lms.iblai.org`) — the app users open | course URLs in reports |
| `STUDIO_ORG` | org key used as the `org` when creating courses (set by hand once; the script preserves it) | `/iblai-api-studio-course-create` |
| `STUDIO_USERNAME` | the signed-in username (read from `GET $LMS_URL/api/user/v1/me`) | LMS calls that need `username` |
| `STUDIO_SESSION` / `STUDIO_CSRF` | Studio cookies `studio_session_id` / `csrftoken` | Studio `-b` cookie + `X-CSRFToken` |
| `LMS_SESSION` / `LMS_CSRF` | LMS cookies `sessionid` / `csrftoken` | LMS `-b` cookie + `X-CSRFToken` |
| `STUDIO_SESSION_EXPIRES` | cookie expiry (ISO) | "is it still valid?" without a request |

The file is `chmod 600` and the script adds it to `.gitignore`. **Never print a
session value** — the script prints `****` + last four only.

### Reading the file from a script (not just the shell)

Session values are **single-quoted** because Django session ids contain `|`
and `:`. `set -a; . ./studio.env; set +a` strips the quotes; a naive parser
does not, and Studio answers a malformed cookie with **HTTP 500 and an HTML
"Studio Server Error" page**, not 401/403. Strip them:

```python
import re
env = {m[1]: m[2].strip().strip("'") for m in (re.match(r"^([A-Z_]+)=(.*)$", l) for l in open("studio.env")) if m}
```

```js
const env = Object.fromEntries([...fs.readFileSync("studio.env","utf8").matchAll(/^([A-Z_]+)=(.*)$/gm)].map(([,k,v]) => [k, v.trim().replace(/^'(.*)'$/, "$1")]));
```

Sanity check: `len(env["STUDIO_SESSION"])` is the cookie length (typically 187), with no quote characters.

## Steps

1. **Run the capture script** from the project directory (needs Node 18+; uses
   Google Chrome / Edge if installed, else Playwright's Chromium; installs
   `playwright-core` into `~/.cache/iblai-studio/` once if no Playwright is
   resolvable — no browser download):

   ```bash
   node .claude/skills/iblai-api-studio-auth/scripts/studio-login.mjs                       # production
   node .claude/skills/iblai-api-studio-auth/scripts/studio-login.mjs --studio https://studio.learn.iblai.org   # test server
   ```

   A browser window opens on `$STUDIO_URL/home`. Tell the user to **sign in
   there themselves** (Studio redirects to the LMS login, then back). Never type
   credentials for them. The script polls once a second for the
   `studio_session_id` + `sessionid` cookies, verifies both, writes the file,
   closes the browser, and prints one line:

   ```
   connected: studio.learn.iblai.app as <username> · session ****ab12 · expires 2026-09-28 → /path/studio.env
   ```

   Flags: `--out <file>` (default `./studio.env`), `--lms <url>`, `--lms-app <url>`,
   `--profile <dir>` (browser profile, default `~/.cache/iblai-studio/profile-<host>`
   — re-runs skip the login while the browser session lasts), `--timeout <s>`
   (default 300). Exit 1 = timed out waiting for a sign-in.

2. **Set the org key** (once): `STUDIO_ORG=<org key>` in `studio.env`. Course
   creation needs the key of the organization the user authors in (the path
   segment after `/platform/` on os.ibl.ai, or `PLATFORM` in `iblai.env`). If
   you do not know it, list the user's roles — `org-instructor` rows carry it:

   ```bash
   set -a; . ./studio.env; set +a
   curl -s -b "studio_session_id=$STUDIO_SESSION; csrftoken=$STUDIO_CSRF" -H "Accept: application/json" \
     "$STUDIO_URL/api/ibl/users/manage/roles/?username=$STUDIO_USERNAME"     # [{"role":"org-instructor","org":"acme","course":""}, …]
   ```

3. **Verify** with the preflight line above.

## No browser available?

Have the user copy the cookies from DevTools (Application → Cookies) on a
signed-in Studio tab: `studio_session_id`, `csrftoken`; and on a signed-in LMS
tab: `sessionid`. Write `studio.env` yourself with the keys above (single-quote
the values), `chmod 600`, add it to `.gitignore`, then run `--check`. Ask for
cookies in a file or env var, never pasted into the chat when avoidable.

## How every Studio call is made (the snippet other skills reuse)

```bash
set -a; . ./studio.env; set +a
S=(-s -b "studio_session_id=$STUDIO_SESSION; csrftoken=$STUDIO_CSRF" -H "X-CSRFToken: $STUDIO_CSRF" \
   -H "Origin: $STUDIO_URL" -H "Referer: $STUDIO_URL/" -H "Accept: application/json" -H "Content-Type: application/json")
curl "${S[@]}" "$STUDIO_URL/api/contentstore/v2/home/courses"
```

- `Accept: application/json` is mandatory — the same URLs return HTML pages without it.
- `X-CSRFToken` + `Origin`/`Referer` on the Studio origin are required on every
  POST/PUT/PATCH/DELETE (Django CSRF checks `Origin` on HTTPS).
- LMS calls use `-b "sessionid=$LMS_SESSION; csrftoken=$LMS_CSRF" -H "X-CSRFToken: $LMS_CSRF" -H "Origin: $LMS_URL" -H "Referer: $LMS_URL/"`.

## Reading failures

| You see | It means | Do |
|---|---|---|
| `302` → `/login/…` (Studio), `401` (LMS API) | session expired or missing | re-run step 1 |
| `403` mentioning CSRF | `X-CSRFToken`/`Origin` missing or stale csrftoken | resend with the snippet; re-run step 1 if it persists |
| `403 {"error":"Permission denied"}` / `"You do not have permission…"` | signed in, but not staff/instructor on that org or course | `/iblai-api-studio-team`, `/iblai-api-management` |
| `500` + HTML "Studio Server Error" on a documented call | almost always a **malformed cookie** (quotes, truncation, wrong file) — or a parameter the skill flags as broken | run `--check`; compare cookie length; re-read the skill's notes |
| HTML page instead of JSON with `200` | missing `Accept: application/json` | add the header |

## Notes

- One `studio.env` = one host. Switching between production and the test server
  means re-running with `--studio` (or keeping two files and `--out`).
- The script never sees or stores a password; the browser profile directory
  under `~/.cache/iblai-studio/` holds the browser's own cookies — delete it to
  force a fresh login.
- Studio's session is created by an OAuth round trip through the LMS
  (`/login/edx-oauth2/` → LMS login → `/complete/edx-oauth2/`), which is why
  the LMS `sessionid` is always available too and why both are captured.
- Headless/CI: there is no service-account path for Studio authoring. For
  org-level user and role administration use `/iblai-api-management`
  (Api-Token); for catalog and enrollment data use `/iblai-api-catalog`.
- Family index and build order: `/iblai-api-studio`.

Attribution

iblaiiblai
View sourceMore from iblai →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →