Sep 20 edition/Reporting & analysis
InfrastructureBusinessSafety

InfrastructureCompute, chips & cloud

datasette-auth-github 1.0 adds configurable 30-day GitHub login cookies for Datasette

Simon Willison’s Datasette GitHub OAuth plugin now sets signed authentication cookies with a configurable lifetime, defaulting to 30 days. The change reduces repeated logins for lightweight data apps, but makes session duration and access revocation a more explicit operational decision.

THE CORE IDEAS4 TAKEAWAYS
01

Version 1.0 changes the plugin from browser-session-style login persistence to a configurable `login_max_age` setting, with a reported default of 30 days. [3] [5] [6]

02

The plugin maps GitHub OAuth sign-ins into Datasette actors, which Datasette’s permission system can then use for access control. [2] [3] [10] [11]

03

Organization and team membership checks are captured at sign-in and stored in the signed cookie, so immediate revocation may require invalidating existing cookies. [3] [8]

04

Release evidence includes PyPI metadata, GitHub release notes, source changes and CI workflow records, but no independent security review or external evaluation was found. [3] [4] [6] [7]

WHY IT MATTERS

Evidence shows a narrow infrastructure change: `datasette-auth-github` 1.0 adds persistent, signed Datasette login cookies with configurable expiry rather than relying on browser-session behavior.

Read the full assessment

For AI teams using Datasette to host internal datasets, evaluation dashboards, retrieval tools or agent-facing demos, the implication is less login friction. The tradeoff is that longer-lived cookies can preserve stale authorization state, so session lifetime, secret rotation and revocation procedures become part of deployment risk management.

Executive brief

On September 19, 2026, Simon Willison released datasette-auth-github 1.0, a Datasette plugin that lets users authenticate to a Datasette instance using GitHub OAuth. The release was prompted by Willison observing that sessions on agent.datasette.io were expiring too often because cookies lacked a Max-Age attribute. Release: datasette-auth-github 1.0 Evidence is mostly maintainer-supplied: the blog post, GitHub release, GitHub issue, source code, PyPI metadata, and Datasette documentation.

Read the full section

On September 19, 2026, Simon Willison released datasette-auth-github 1.0, a Datasette plugin that lets users authenticate to a Datasette instance using GitHub OAuth. The release is small but operationally meaningful: the plugin now sets authentication cookies with a configurable lifetime rather than relying on browser-session cookies. The new default is 30 days, controlled by a login_max_age setting. The release was prompted by Willison observing that sessions on agent.datasette.io were expiring too often because cookies lacked a Max-Age attribute. Release: datasette-auth-github 1.0

This is not an AI-model release and no model/version is involved. Its relevance to AI practitioners is infrastructural: Datasette is often used to expose datasets, internal SQLite-backed tools, demos, and agent-facing data interfaces. For teams putting AI demos, internal retrieval tools, or evaluation dashboards behind lightweight authentication, this release reduces login churn but increases the importance of explicitly thinking about session lifetime and access revocation. Datasette’s own documentation emphasizes that authentication is largely handled by plugins, while Datasette’s permission system operates on an “actor” object associated with each request. Authentication and permissions - Datasette documentation

Evidence is mostly maintainer-supplied: the blog post, GitHub release, GitHub issue, source code, PyPI metadata, and Datasette documentation. No independent testing or security review of this specific 1.0 release was found in the reviewed sources. PyPI does, however, independently show that release artifacts for version 1.0 were uploaded on September 19, 2026, using Trusted Publishing, with attestations tied to GitHub Actions and commit 1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e. datasette-auth-github · PyPI

What changed and event timeline

  1. Prior behavior

    According to the maintainer’s issue and release note, the plugin had been setting ds_actor cookies without a browser Max-Age, causing them to behave as session cookies.

    More detail

    Willison reported that this led to being logged out frequently when visiting agent.datasette.io, particularly in Mobile Safari. This claim is maintainer-reported; no independent reproduction was found in the reviewed sources.

  2. Fix

    Release 1.0 changes the cookie behavior so cookies last login_max_age seconds by default

    The GitHub release says the default is 30 days and links the change to issue #80.

    More detail

    The PyPI 1.0 README documents login_max_age as a positive integer number of seconds and gives 86400 as a 24-hour example.

  3. PyPI release history shows the first 0.1 release of datasette-auth-github.

  4. PyPI shows release 0.14, the version immediately preceding 1.0 in the release history.

  5. Issue #80 was opened, describing the session-cookie problem.

  6. GitHub shows release 1.0, with the cookie lifetime change.

  7. PyPI lists datasette-auth-github 1.0 as the latest release and shows both source distribution and wheel files uploaded that day.

  8. GitHub Actions shows a successful release-triggered publish workflow and a separate test workflow for the 1.0 commit.

Capabilities and access

datasette-auth-github is a Datasette plugin for GitHub authentication, not an authorization server or full identity-management system. The documented setup requires installing the plugin, creating a GitHub OAuth app, setting the callback URL to /-/github-auth-callback, and configuring client_id and client_secret in Datasette plugin configuration—preferably via environment variables rather than hard-coded metadata.

Read the full section

datasette-auth-github is a Datasette plugin for GitHub authentication, not an authorization server or full identity-management system. The documented setup requires installing the plugin, creating a GitHub OAuth app, setting the callback URL to /-/github-auth-callback, and configuring client_id and client_secret in Datasette plugin configuration—preferably via environment variables rather than hard-coded metadata. datasette-auth-github · PyPI

Once signed in, the plugin produces a Datasette actor containing GitHub-derived fields such as id, display, gh_id, gh_login, gh_email, and optionally gh_orgs or gh_teams when organization/team loading is configured. datasette-auth-github · PyPI Access can then be controlled using Datasette allow rules, including restrictions by GitHub login, stable GitHub user ID, organization, or team membership. datasette-auth-github · PyPI

There is no AI model, inference endpoint, benchmark, token context length, or model safety card associated with this release.

Technical analysis for researchers and developers

The plugin integrates with Datasette via the datasette plugin entry point and registers two routes: /-/github-auth-start and /-/github-auth-callback. The first route redirects users to GitHub’s OAuth authorization endpoint; the second exchanges the returned code for an access token, fetches the GitHub user profile, constructs a Datasette actor, and sets a signed ds_actor cookie.

Read the full section

Architecture

The plugin integrates with Datasette via the datasette plugin entry point and registers two routes: /-/github-auth-start and /-/github-auth-callback. The first route redirects users to GitHub’s OAuth authorization endpoint; the second exchanges the returned code for an access token, fetches the GitHub user profile, constructs a Datasette actor, and sets a signed ds_actor cookie. [](https://raw.githubusercontent.com/simonw/datasette-auth-github/1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e/datasette_auth_github/__init__.py)

The OAuth flow aligns with GitHub’s documented web application flow: redirect to GitHub, redirect back to the application, then use the access token to call the GitHub API on behalf of the user. GitHub’s documentation describes this flow and the use of the access token for requests such as GET /user. Authorizing OAuth apps - GitHub Docs

The key new implementation detail is in views.py: DEFAULT_LOGIN_MAX_AGE is set to 30 * 24 * 60 * 60; verify_config() validates that login_max_age is either None or a positive integer; and the callback sets a signed ds_actor cookie with max_age=login_max_age. If login_max_age is not None, the plugin also places a signed expiry value in the cookie payload under "e", using a base62-encoded timestamp. [](https://raw.githubusercontent.com/simonw/datasette-auth-github/1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e/datasette_auth_github/views.py)

That two-layer design matters. Max-Age controls browser retention, while the signed "e" value allows Datasette to reject an otherwise-present cookie after expiration. Datasette’s own authentication documentation describes this optional signed expiry timestamp mechanism for ds_actor cookies. Authentication and permissions - Datasette documentation

The cookie is set as HttpOnly, SameSite=Lax, path /, and Secure only when the request scheme is HTTPS. [](https://raw.githubusercontent.com/simonw/datasette-auth-github/1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e/datasette_auth_github/views.py) MDN recommends HttpOnly for session identifiers and recommends Secure for cookies transmitted over HTTPS; it also notes that cookies without Expires or Max-Age are session cookies. Set-Cookie header - HTTP | MDN

Organization and team authorization

When load_orgs or load_teams is configured, the plugin requests the read:org OAuth scope; otherwise it requests user:email. [](https://raw.githubusercontent.com/simonw/datasette-auth-github/1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e/datasette_auth_github/views.py) The helper code checks configured organizations and teams during sign-in and adds matching gh_orgs or gh_teams values to the actor. [](https://raw.githubusercontent.com/simonw/datasette-auth-github/1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e/datasette_auth_github/utils.py)

This has an important revocation implication: organization and team memberships are captured at sign-in and persisted in the signed cookie. The 1.0 README explicitly warns that a removed user can continue to access the Datasette instance until the cookie expires or is invalidated; it recommends rotating DATASETTE_SECRET to invalidate existing cookies. datasette-auth-github · PyPI

Evaluation methodology and reproducibility

The documented test coverage is CI-based rather than an external evaluation. GitHub Actions shows a test workflow for the 1.0 commit with a matrix across Python 3.10, 3.11, 3.12, 3.13, and 3.14, and across Datasette dependency ranges "<1.0" and ">=1.0a20". The workflow installs the package, installs the matrix-selected Datasette version, and runs python -m pytest. Release version 1.0 · simonw/datasette-auth-github@1d47f69 · GitHub GitHub’s Actions page also shows the relevant test and publish workflows completing around the 1.0 release. 1.0 · simonw/datasette-auth-github@1d47f69 · GitHub

What is not documented: independent penetration testing, browser compatibility testing beyond the maintainer’s anecdote, formal threat modeling, load testing, or a complete test-result artifact accessible without GitHub login. The available workflow status supports “CI passed,” not “security verified.”

Claims and evidence

  • Version 1.0 was released on September 19, 2026. — Maintainer + registry
  • The main change is replacing browser-session cookies with cookies lasting login max age , defaulting to 30 days. — Maintainer + source/PyPI
  • The original problem was frequent logouts because cookies lacked Max-Age . — Maintainer-reported
Read the full section
Material claimEvidence typeSupport
Version 1.0 was released on September 19, 2026.Maintainer + registryGitHub release and PyPI release metadata. Release 1.0 · simonw/datasette-auth-github · GitHub
The main change is replacing browser-session cookies with cookies lasting login_max_age, defaulting to 30 days.Maintainer + source/PyPIGitHub release, PyPI README, source code. Release 1.0 · simonw/datasette-auth-github · GitHub
The original problem was frequent logouts because cookies lacked Max-Age.Maintainer-reportedBlog post and issue #80. No independent reproduction found. Release: datasette-auth-github 1.0
The plugin uses GitHub OAuth and sets a signed Datasette ds_actor cookie.Source + DocsPlugin source and Datasette authentication docs. [](https://raw.githubusercontent.com/simonw/datasette-auth-github/1d47f69f5a38e36e8b8a861d42b1a3b722b09e8e/datasette_auth_github/views.py)
Artifacts were uploaded to PyPI with Trusted Publishing and provenance attestations.Registry-reportedPyPI 1.0 page. datasette-auth-github · PyPI
Tests ran across multiple Python and Datasette versions.CI-reportedGitHub Actions workflow file and run listing. Release version 1.0 · simonw/datasette-auth-github@1d47f69 · GitHub

Context and prior work

Datasette’s architecture deliberately leaves most authentication mechanisms to plugins. datasette-auth-github fits this model by translating a GitHub OAuth identity into a Datasette actor and then relying on Datasette’s permission system for access control. datasette-auth-github · PyPI The plugin is mature in the narrow sense that it has existed since 2019 on PyPI, with a history of releases through 2026.

Read the full section

Datasette’s architecture deliberately leaves most authentication mechanisms to plugins. Its documentation says plugins can support authenticated users via cookies and API agents via tokens, and that each request has an associated actor value available as request.actor. Authentication and permissions - Datasette documentation datasette-auth-github fits this model by translating a GitHub OAuth identity into a Datasette actor and then relying on Datasette’s permission system for access control. datasette-auth-github · PyPI

The plugin is mature in the narrow sense that it has existed since 2019 on PyPI, with a history of releases through 2026. datasette-auth-github · PyPI But “1.0” should not be overread as an independent assurance claim. Here it appears to mean the maintainer considers the plugin stable enough, helped by compatibility testing against pre-1.0 and 1.0-alpha Datasette versions. Release: datasette-auth-github 1.0

Limitations, safety, and contested findings

The main security tradeoff is straightforward: longer-lived cookies improve usability but extend the window during which stale authorization data can be used. A public demo may tolerate 30 days; an internal evaluation dashboard containing proprietary prompts, model outputs, customer data, or red-team results may require a shorter lifetime and a documented revocation process.

Read the full section

The main security tradeoff is straightforward: longer-lived cookies improve usability but extend the window during which stale authorization data can be used. That is particularly relevant for org/team-based access because memberships are checked at sign-in and stored in the signed cookie. datasette-auth-github · PyPI

Operationally, teams should set login_max_age according to data sensitivity. A public demo may tolerate 30 days; an internal evaluation dashboard containing proprietary prompts, model outputs, customer data, or red-team results may require a shorter lifetime and a documented revocation process. Datasette’s signed expiry support helps, but it does not replace identity-provider-side session management or continuous authorization checks. Authentication and permissions - Datasette documentation

No conflicting independent evidence about the release was found in the reviewed sources. The main caveat is absence of independent corroboration: the bug report, fix rationale, and stability judgment all come from the maintainer or project infrastructure.

Business and practitioner implications

For business leaders, the practical takeaway is that this release lowers friction for GitHub-authenticated Datasette deployments. If your team uses Datasette for internal data catalogs, lightweight AI evaluation UIs, agent demos, or customer-facing prototypes, fewer unexpected logouts can improve usability.

Read the full section

For business leaders, the practical takeaway is that this release lowers friction for GitHub-authenticated Datasette deployments. If your team uses Datasette for internal data catalogs, lightweight AI evaluation UIs, agent demos, or customer-facing prototypes, fewer unexpected logouts can improve usability.

For developers, the upgrade consideration is mostly configuration review:

  • confirm datasette-auth-github==1.0 is installed;
  • decide whether the 30-day default is appropriate;
  • set login_max_age explicitly for regulated or sensitive deployments;
  • use stable GitHub IDs rather than mutable usernames for critical allow rules;
  • rotate DATASETTE_SECRET when org/team membership changes require immediate revocation;
  • confirm HTTPS/proxy configuration so the cookie’s Secure behavior is correct in production.

For security teams, treat this as a session-management change, not as a new authentication assurance level.

Sources

Primary and registry sources: Simon Willison’s release post; GitHub release and issue #80; PyPI 1.0 metadata and provenance; source files for plugin routes and OAuth callback. Supporting technical sources: Datasette authentication/plugin documentation, GitHub OAuth documentation, and MDN cookie guidance. Independent evaluation of this specific release was not found.

FOLLOW THE EVIDENCE

The source trail.

Sources (10)
A LITTLE LESS NOISE. A LOT MORE CONTEXT.

Stay curious.
Follow the evidence.

Independent perspectives, the original sources, and room for the questions that don't have easy answers.

How we build the brief