npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@m-kopa/platform-auth-container

v0.1.0

Published

Container-side identity adapter for the Launchpad Worker. Reads the Worker-injected X-User-* identity headers and exposes a typed User to HTTP handlers. Optional Express middleware adapter.

Downloads

92

Readme

@m-kopa/platform-auth-container

Container-side identity adapter for the Launchpad Worker.

The Launchpad Worker (see ADR 0015 Decision 4) is the canonical trust boundary for the container shape. The target state is for the Worker to verify Cf-Access-Jwt-Assertion against Cloudflare Access and forward the trusted claims as X-User-* headers on every request it dispatches into the container Durable Object. The container trusts those headers because the DO stub is the only ingress — Cloudflare's edge will not route external traffic to the container directly.

Status today: the chunk-C Worker only does a fail-closed presence check on Cf-Access-Jwt-Assertion — full RS256 + iss + aud verification and X-User-* injection still need to land on the Worker side (see Worker contract (status) below).

This package is the container-side counterpart. It:

  1. Reads the Worker-injected X-User-* headers.
  2. Exposes a typed User to HTTP handlers.
  3. Optionally provides an Express middleware adapter.

Status

Pre-1.0. Consumers MUST pin exact versions. New error codes and new optional User fields may land in minor versions; existing field shapes are stable.

Worker contract (status)

At time of writing the Worker only does a fail-closed presence check on Cf-Access-Jwt-Assertion — it does not yet inject the X-User-* headers this package reads. A follow-up will add JWT verification + header injection on the Worker side. Until then the container's /me-style routes will see MISSING_IDENTITY and respond 401.

The Worker is expected to set the following headers, all parsed by the canonical names exported as IDENTITY_HEADER:

| Header | Required | Meaning | | --- | --- | --- | | X-User-Sub | yes | Cloudflare Access sub claim (stable subject). | | X-User-Preferred-Username | no | JWT preferred_username claim. | | X-User-Email | no | JWT email claim. | | X-User-Groups | no | Comma-separated group memberships. |

Install

bun add @m-kopa/[email protected]

.npmrc must scope @m-kopa to GitHub Packages:

@m-kopa:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}

Usage — runtime-agnostic

import { readUserFromHeaders } from "@m-kopa/platform-auth-container";

app.get("/api/me", (req, res) => {
  const user = readUserFromHeaders(req.headers);
  res.json(user);
});

readUserFromHeaders accepts either a Web-standard Headers instance or a Node IncomingHttpHeaders-shaped dictionary.

Usage — Express middleware

import {
  createPlatformAuthMiddleware,
  type PlatformAuthRequest,
} from "@m-kopa/platform-auth-container/express";

const app = express();
app.use(createPlatformAuthMiddleware());

app.get("/api/me", (req, res) => {
  // The parsed `User` is on `req.user` by default. Pass `userKey:
  // "principal"` to the factory to change the field name; cast to
  // `PlatformAuthRequest<"principal">` accordingly.
  const typedReq = req as PlatformAuthRequest;
  res.json(typedReq.user);
});

express is declared as an optional peer dependency — the main entrypoint of this package does not import it.

Error handling

A single sealed error class, IdentityHeaderError, surfaces parse failures. Consumers MUST narrow on code, never on message.includes(...).

import { IdentityHeaderError } from "@m-kopa/platform-auth-container";

try {
  const user = readUserFromHeaders(req.headers);
} catch (err) {
  if (err instanceof IdentityHeaderError) {
    switch (err.code) {
      case "MISSING_IDENTITY":
        // No X-User-Sub header — request did not arrive through
        // the Worker's identity-injection path. Respond 401.
        return res.status(401).end();
      case "MALFORMED_IDENTITY":
        // X-User-Sub was present but empty after trim. This
        // indicates a Worker-side bug — log it loudly.
        return res.status(401).end();
    }
  }
  throw err;
}

A non-throwing variant is also exported:

import { tryReadUserFromHeaders } from "@m-kopa/platform-auth-container";

const user = tryReadUserFromHeaders(req.headers);  // User | null
if (!user) return res.status(401).end();

tryReadUserFromHeaders only swallows MISSING_IDENTITY. A MALFORMED_IDENTITY still throws because silently treating it as anonymous would mask a Worker bug.

Sanitisation contract

IdentityHeaderError.message names the structural fact that failed (which header was missing, "empty after trim"). It MUST NOT include the raw header value bytes — even though the X-User-* headers are not secrets per se, they are user-identifying and a wide-net error log should not leak them. The parser constructs messages from header names, not values.

TODO (follow-up work)

  • Worker-side injection. The chunk-C Worker (launchpad-template/container/worker/index.ts) currently forwards only X-Bindings-Proxy-* and X-Request-ID. A follow-up needs to add the JWT verification step (using @m-kopa/platform-auth) and inject the four X-User-* headers documented above.
  • Group-membership helpers. A hasGroup(user, name) / requireGroup(name) middleware may follow once we have real RBAC requirements from a launching app.

References

  • Milestone: M-1071 (chunk D2 of the seven-chunk plan).
  • ADR 0015 Decision 4 — container auth posture.
  • ADR 0016 — container-shape TF wiring.
  • @m-kopa/platform-auth — JWT verification (used inside the Worker; this package is the container-side counterpart).
  • @m-kopa/platform-bindings-client — sibling package, same package shape and pre-1.0 conventions.