{
  "$type": "site.standard.document",
  "canonicalUrl": "https://happyview.app/blog/happyview-2.10",
  "description": "Service identity, permissioned spaces, and new blob utilities.",
  "path": "/blog/happyview-2.10",
  "publishedAt": "2026-06-30T00:00:00.000Z",
  "site": "at://did:plc:qneu5uamqs6cug7sjobbaexm/site.standard.publication/3mpokbucn3y26",
  "tags": [
    "announcements"
  ],
  "textContent": "This one's been a long time coming. HappyView finally has a real AT Protocol identity, can do service proxying, and permissioned spaces got a big update to match the official spec.\n\nService identity\n\nWhen a user's PDS routes a request to your AppView, it resolves the destination by looking up your DID. Without a service identity, that lookup fails and standard atproto routing can't reach you.\n\nHappyView offers three modes:\n\n- Domain identity (did:web) - Your domain name becomes your identity. HappyView generates a signing keypair and serves a DID document at /.well-known/did.json automatically. The simplest option.\n- Network identity (did:plc) - Registers a new identity in the PLC directory. This is the most durable option — it survives domain changes if you ever need to migrate.\n- Linked account - Link your AppView to an existing AT Protocol account.\n\nWith a service identity in place, HappyView can act as a service proxy. A PDS sends a request with an atproto-proxy header pointing at your AppView, HappyView verifies the caller via service auth, runs your XRPC handler, and responds. This is how atproto apps are _supposed_ to work! Up to this point HappyView only supported direct connections via DPoP.\n\nFull docs: Service Identity.\n\nPermissioned spaces alignment\n\nThis is the big one. The spaces implementation now aligns with Dan's proposal, and if you were using the experimental spaces API before, this is a breaking change.\n\nNamespace split\n\nEndpoints moved from dev.happyview.space. to two namespaces:\n\n- com.atproto.space. - protocol-level routes (queries, data access, credentials)\n- com.atproto.simplespace. - management routes (create/update/delete spaces, membership)\n\nThe old dev.happyview.space. endpoints will work as aliases until HappyView v3.\n\nAccess model rewrite\n\nThe old accessMode / appAllowlist / appDenylist system is gone.\n\nMint policy controls who can create permissioned repos in a space:\n\n- member-list (default) - only members\n- public - anyone\n- managing-app - only the managing app\n\nApp access controls which third-party apps can interact with the space:\n\n- open (default) - any app\n- allowList - only explicitly listed apps\n\nAlso, getMemberGrant is now getDelegationToken (and it's a GET, not a POST).\n\nNew concepts\n\n- Authority DID replaces owner_did. There's also a new creator_did for tracking who originally created the space\n- read_self access level - members can only read their own data within the space\n- Deniable commit signatures - per-user repo state uses LtHash (homomorphic set-hash) with deniable signatures. The user signs context (space + rev + random input keying material), not content\n- Record operation log - listRepoOps returns the oplog for sync\n- Write notifications - registerNotify, notifyWrite, notifySpaceDeleted\n\nFull docs: Permissioned Spaces.\n\nBlob utilities for Lua\n\nTwo new Lua functions — atproto.blob_download and atproto.blob_upload — let scripts perform some new magic. For example, you can migrate a blob one PDS to another in just a couple of lines:\n\nFull docs: atproto API (blob_download / blob_upload).\n\nPrefixed database tables\n\nAll HappyView tables are now prefixed with happyview_ (e.g. records -> happyview_records) so they won't collide with your own tables if you're sharing a database. Existing databases are migrated automatically.\n\nIf you use db.raw() in Lua scripts to query HappyView tables directly, you'll need to update your queries to use the prefixed names.\n\nEverything else\n\n- Setup wizard hardening - the setup flow handles edge cases better, especially around re-auth and preventing unauthenticated redirects\n- Dynamic cookie security - cookies now set their security flags based on the request context, which fixes some issues with service proxying behind a reverse proxy\n- Bluesky PDS scope handling - fixed a compat issue with the scope format Bluesky's PDS returns during OAuth\n\nGo play\n\nFull changelog is on GitHub. If you have questions, feature requests, or just need a little help, join the Cartridge Discord Server and hop into the #happyview channel.",
  "title": "HappyView v2.10"
}