Add Ghostlight Dungeon Heimdall profile
This commit is contained in:
parent
758892db87
commit
210e16220f
5 changed files with 56 additions and 3 deletions
25
docs/app-profiles/ghostlight.md
Normal file
25
docs/app-profiles/ghostlight.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Ghostlight Dungeon Access Profile
|
||||
|
||||
Ghostlight Dungeon reuses Heimdall's browser-completion Discord sign-in path.
|
||||
Heimdall owns provider OAuth, local account identity, signed access claims, and
|
||||
refresh. Ghostlight verifies claims locally and owns campaigns, campaign
|
||||
membership, current campaign selection, and every world mutation.
|
||||
|
||||
## App identity
|
||||
|
||||
- `app_slug`: `ghostlight`
|
||||
- public URL: `https://yggdrasil.gamecult.org/ghostlight/`
|
||||
- identity provider: Discord
|
||||
- public-demo rule: any Heimdall-authenticated Discord identity receives
|
||||
`app_access`; no GameCult guild role is required
|
||||
|
||||
## Capabilities
|
||||
|
||||
- `app_access`: shared capability granting entry to the demo
|
||||
- `campaign_play`: hybrid capability; Ghostlight must also prove that the
|
||||
authenticated account owns the selected campaign
|
||||
|
||||
The browser never carries provider tokens. It receives a one-time completion
|
||||
code, Ghostlight redeems it server-to-server, verifies the resulting
|
||||
`aud=ghostlight` claim against Heimdall JWKS, and establishes app-local campaign
|
||||
authority.
|
||||
|
|
@ -197,11 +197,38 @@ const bifrostProfile: AppProfile = {
|
|||
},
|
||||
};
|
||||
|
||||
const ghostlightProfile: AppProfile = {
|
||||
slug: "ghostlight",
|
||||
displayName: "Ghostlight Dungeon",
|
||||
profileVersion: "2026-08-19",
|
||||
identityProviders: ["discord"],
|
||||
entitlementSources: [],
|
||||
managedConnectionProviders: [],
|
||||
capabilities: [
|
||||
{
|
||||
key: "app_access",
|
||||
mode: "shared",
|
||||
summary: "May enter the public Ghostlight Dungeon demo.",
|
||||
sharedRule: identityFacts.authenticated,
|
||||
},
|
||||
{
|
||||
key: "campaign_play",
|
||||
mode: "hybrid",
|
||||
summary: "May play campaigns owned by the authenticated Ghostlight account.",
|
||||
localRequirement: "Ghostlight must combine app_access with local campaign ownership.",
|
||||
},
|
||||
],
|
||||
evaluateSharedCapabilities(context) {
|
||||
return context.facts.has(identityFacts.authenticated) ? ["app_access"] : [];
|
||||
},
|
||||
};
|
||||
|
||||
export const appProfiles: Record<AppSlug, AppProfile> = {
|
||||
repixelizer: repixelizerProfile,
|
||||
streampixels: streampixelsProfile,
|
||||
spotiverse: spotiverseProfile,
|
||||
bifrost: bifrostProfile,
|
||||
ghostlight: ghostlightProfile,
|
||||
};
|
||||
|
||||
export function getAppProfile(appSlug: AppSlug): AppProfile {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ export const providers = ["discord", "patreon", "github", "twitch", "youtube", "
|
|||
|
||||
export type Provider = (typeof providers)[number];
|
||||
|
||||
export const appSlugs = ["repixelizer", "streampixels", "spotiverse", "bifrost"] as const;
|
||||
export const appSlugs = ["repixelizer", "streampixels", "spotiverse", "bifrost", "ghostlight"] as const;
|
||||
|
||||
export type AppSlug = (typeof appSlugs)[number];
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ describe("Heimdall verse runtime publication", () => {
|
|||
runtime: {
|
||||
storageBackend: "postgres",
|
||||
configuredProviders: ["discord", "twitch"],
|
||||
appProfileCount: 4,
|
||||
appProfileCount: 5,
|
||||
},
|
||||
});
|
||||
expect(bySchema.get("heimdall.command_boundary.v1")).toMatchObject({
|
||||
|
|
@ -56,7 +56,7 @@ describe("Heimdall verse runtime publication", () => {
|
|||
expect(bySchema.get("idunn.daemon_health")).toEqual([
|
||||
"yggdrasil-heimdall",
|
||||
"active",
|
||||
"Heimdall auth runtime active; storage=postgres; providers=2/6; apps=4; healthTransport=CultNet/RUDP",
|
||||
"Heimdall auth runtime active; storage=postgres; providers=2/6; apps=5; healthTransport=CultNet/RUDP",
|
||||
"2026-06-16T17:10:00.000Z",
|
||||
"heimdall.cultnet-rudp-provider-health",
|
||||
"daemon-published",
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ describe("Heimdall Verse witness advertisement", () => {
|
|||
"streampixels",
|
||||
"spotiverse",
|
||||
"bifrost",
|
||||
"ghostlight",
|
||||
]);
|
||||
expect(advertisement.documents.map((document) => document.schemaId)).toEqual([...heimdallWitnessSchemaIds]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue