Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
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
  • Authors
  • 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
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Browser

ASecurity

Drive a real browser for a task that needs one — a web login, an end-to-end check, verifying a UI, reaching something behind auth — with credentials pulled from a vault so charter hands the password to the browser instead of you typing it into the conversation. Use when browser automation needs to authenticate, or when several workers each need their own logged-in session.

6 stars
0 votes
0 copies
1 views
Added 10/2/2026
testinggobashnodegit

Works with

climcp

Security Analysis

A100/100

Scanned 10/2/2026

$npx -y skills add diazoxide/charter --skill browser --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Browser?

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

Security grade badge for Browser
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/diazoxide-browser-charter/badge)](https://www.skillsdirectory.com/skills/diazoxide-browser-charter)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: browser
description: Drive a real browser for a task that needs one — a web login, an end-to-end check, verifying a UI, reaching something behind auth — with credentials pulled from a vault so charter hands the password to the browser instead of you typing it into the conversation. Use when browser automation needs to authenticate, or when several workers each need their own logged-in session.
---

# Driving a browser with vault credentials

Two different projects own the two halves of this:

- **How to drive a page** belongs to Playwright: snapshots, clicking, network mocking,
  tracing. Generate its reference into this plane once:

  ```bash
  charter browser install          # writes .claude/skills/playwright-cli/
  ```

  charter ships none of those pages. They are Apache-2.0, and they change far more often
  than charter releases. To update them, run that command again rather than editing them.
  It runs `npx`, so it needs Node.js. `--version` pins an exact version.

  The command also gitignores `.playwright-cli/`, which is where traces and snapshots land.
  A trace holds the network traffic of whatever it recorded, logins included. Whether to
  commit the generated pages and `.playwright/cli.config.json` is the plane's choice.

- **Where credentials come from, and how parallel workers stay isolated** is what this
  skill covers.

## One session per worker

Each worker passes its own `-s=<name>`. Sessions hold independent cookies, localStorage,
IndexedDB, cache and tabs, so N workers can each be logged in as a different user at once.

```bash
npx @playwright/cli@<version> -s=owner  open https://example.test/
npx @playwright/cli@<version> -s=viewer open https://example.test/
npx @playwright/cli@<version> list          # live sessions
npx @playwright/cli@<version> -s=owner close
```

**Pin the version in every command.** A session belongs to the *version* that opened it.
Two commands that resolve different versions look at different daemons. The second then
reports `The browser 'owner' is not open` while the first browser is still alive and logged
in.

## Credentials: never typed, never printed

`charter secret exec --dotenv` resolves vault keys into one 0600 temp file and points
`PLAYWRIGHT_MCP_SECRETS_FILE` at it. You then refer to a secret **by name**. Playwright
substitutes the value and scrubs it from the output it captures.

That is a net, not a boundary. A step that transforms or forwards the value is not scrubbed:
a screenshot, an `eval`, a POST. The credential goes wherever you send it.

Three rules for the flow:

- **Open the session inside the bridge.** `playwright-cli` reads
  `PLAYWRIGHT_MCP_SECRETS_FILE` once, when the session starts. Setting it later, on a `fill`
  against a session that is already open, fails silently: the literal string `PASS` is typed
  into the field. Wrap the whole flow in one `charter secret exec`, from `open` through the
  last `fill`.
- **Wait for each field before filling it.** `open` returns before an identity provider's
  redirect lands. A `fill` that runs too early fails with "does not match any elements",
  which looks like a wrong selector.
- **`not open` is not a cue to re-open.** A second `open` with the same `-s=<name>` starts a
  new browser and orphans the logged-in one. The dotenv file is gone once `charter secret
  exec` exits, so the new browser cannot be filled either. Re-run the whole flow instead.

```bash
charter secret exec <vault> \
  --dotenv PLAYWRIGHT_MCP_SECRETS_FILE=USER:<user-key> \
  --dotenv PLAYWRIGHT_MCP_SECRETS_FILE=PASS:<pass-key> \
  -- bash -c '
    P="npx @playwright/cli@<version> -s=owner"
    wait_for() {
      for _ in $(seq 1 15); do
        $P eval "() => !!document.querySelector(\"$1\")" 2>/dev/null | grep -q true && return 0
        sleep 2
      done
      echo "TIMEOUT waiting for $1" >&2; return 1
    }
    $P open https://example.test/
    wait_for "#username" || exit 1
    $P fill "#username" USER
    wait_for "#password" || exit 1
    $P fill "#password" PASS
    $P click "button[type=submit]"
    $P snapshot
  '
```

To read the **active persona's** vault instead of naming one, use `charter persona secret
exec`. A different fixture account is a different pair of keys, not a different mechanism.

Reading a token *out of* a logged-in session through the vault (a `browser://` reference)
is not in this version yet. Do not stand in for it with `TOKEN=$(… cookie-get …)`: that is
command substitution into the transcript, with nothing to redact it.

## Hard rules

- **Never read a filled secret back.** Do not evaluate `el.value`, take a screenshot of a
  filled password field, or dump the dotenv file.
- Never type a credential in directly, even "just once to test". Use the bridge.
- Never commit a session directory, a storage-state file or a trace. Each one holds live
  cookies or authenticated traffic, which is the credential in another form.

Attribution

diazoxidediazoxide
View sourceSee grades on GitHubMore from diazoxide →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

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

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Screen Reader Testing

Practical guide to testing web applications with screen readers for comprehensive accessibility validation.

401991 votes

Tdd Workflow

在编写新功能、修复错误或重构代码时使用此技能。强制执行测试驱动开发,包含单元测试、集成测试和端到端测试,覆盖率超过80%。

2456590 votes

Eval Harness

克劳德代码会话的正式评估框架,实施评估驱动开发(EDD)原则

2456590 votes

Python Testing

使用pytest、TDD方法、夹具、模拟、参数化和覆盖率要求的Python测试策略。

2456590 votes

Django Tdd

Django测试策略,包括pytest-django、TDD方法论、factory_boy、模拟、覆盖率以及测试Django REST Framework API。

2456590 votes
View all in testing →