Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/perch-authz-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: perch-authz-console PR preview (GitHub Pages)

# Per-PR live preview of examples/perch-authz-console/ on GitHub Pages, deployed
# to the `gh-pages` branch under `pr-preview/pr-<N>/` and torn down when the PR
# closes. The preview URL is:
# https://<owner>.github.io/<repo>/pr-preview/pr-<N>/
#
# ONE-TIME SETUP the maintainer must do: set the repo's Pages source to "Deploy
# from a branch → gh-pages / (root)". The existing pages.yml deploys the
# status-message example via the *Actions* Pages source, which is mutually
# exclusive with a branch source — so choose one, or give this example its own
# Pages target. The example build uses a relative base (`--base=./`) so it works
# at any subpath regardless of that choice.

on:
pull_request:
types: [opened, synchronize, reopened, closed]
paths:
- "examples/perch-authz-console/**"
- "packages/testkit/**"
- ".github/workflows/perch-authz-preview.yml"

permissions:
contents: write
pull-requests: write

concurrency:
group: perch-authz-preview-${{ github.ref }}
cancel-in-progress: true

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v5
with:
node-version: "20"
cache: npm

- name: Install dependencies
run: npm ci

# The example imports @nidohq/testkit, which publishes a built dist/.
- name: Build the testkit
run: npm run build -w @nidohq/testkit

# Relative base so the bundle loads from the pr-preview subpath.
- name: Build the example (relative base)
run: npm run build:preview
working-directory: examples/perch-authz-console

- name: Deploy / update / tear down the PR preview
uses: rossjrw/pr-preview-action@v1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium Severity severity

Resource Management: Unpinned third-party GitHub Action in deploy job

The workflow uses rossjrw/pr-preview-action@v1, a mutable tag. If the upstream action is compromised or the tag is retargeted, the workflow’s granted contents: write permission could be abused to push malicious content to gh-pages (and potentially modify repository content within the workflow’s scope).

Pin GitHub Actions to an immutable commit SHA (and optionally use GitHub’s dependency review / allowlist). Minimize permissions (e.g., use fine-grained permissions or separate deploy token) where feasible.


Actions
  • Reply /almanax ask <question> to ask a follow-up question.
  • Reply /almanax dismiss [<reason>] and it won't appear again in future scans.
  • Reply /almanax resolve [<reason>] to mark the finding as resolved.
  • Reply /almanax severity <level> [<reason>] to override the severity.

with:
source-dir: examples/perch-authz-console/dist
preview-branch: gh-pages
umbrella-dir: pr-preview
7 changes: 7 additions & 0 deletions examples/perch-authz-console/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
dist/
artifacts/
test-results/
playwright-report/
.playwright/
*.local
58 changes: 58 additions & 0 deletions examples/perch-authz-console/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# perch × Nido — Authorization Console

A dApp that **logs in a local-key Nido smart account** (no passkey), visualizes
its perch authorization policy, simulates `__check_auth` locally, and lets you
build more complex policies — including a **post-quantum ML-DSA** signer.

Everything is real and local: the account C-address, the signatures, the perch
`doc_hash`, and the allow/deny verdicts all come from
[`@nidohq/testkit`](../../packages/testkit) (nidohq/nido#188). No network, no
contracts deployed.

## Run it

```sh
npm install # from the repo root (workspaces)
npm run dev -w perch-authz-console
```

## What it shows

- **Wallet login including Nido** — a `NidoLocalModule` implementing the
`@creit.tech/stellar-wallets-kit` `ModuleInterface`, so Nido is a wallet any
kit dApp can connect — here with a **local key** instead of a passkey.
- **Every verifier** — one signer each for **secp256r1** (the real
`webauthn-verifier`, driven by a local P-256 key), **ed25519**, and
**ML-DSA-65** (post-quantum). The last two, and perch on-chain, are simulated
ahead of their contracts (ML-DSA groundwork: nido#143).
- **Reachable calls** — what each key can actually do, derived from the policy.
- **Simulate `__check_auth`** — pick a call + signers → Kleene verdict + trace.
- **Build a policy** — add rules (scope, functions, arg predicates, spend cap);
the `doc_hash` updates live.
- **Attenuate** — narrow a rule with the fail-closed subset check
(`reachable(child) ⊆ reachable(parent)`); widening is refused.

## Verify (browser snapshots)

```sh
npx playwright install chromium
npm run test:e2e -w perch-authz-console # drives the full flow, writes artifacts/*.png
```

## Deploy

- `npm run build` — local/apex build (base `/`).
- `npm run build:pages` — GitHub Pages project build (`--base=/<repo>/`).
- `npm run build:preview` — relative base (`./`), for per-PR subpath previews.

A per-PR GitHub Pages preview workflow is at
`.github/workflows/perch-authz-preview.yml`. It deploys to the `gh-pages` branch
under `pr-preview/pr-<N>/`; enabling it requires the repo's Pages source to
serve that branch (see the workflow header).

## Roadmap

The simulator is a faithful TS model. Next, behind the same call: run the real
`soroban-env` in the browser (wasmi) backed by
[rs-soroban-sdk#1657](https://github.com/stellar/rs-soroban-sdk/pull/1657)'s
local-storage cache — lazy testnet pulls, otherwise fully offline.
14 changes: 14 additions & 0 deletions examples/perch-authz-console/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>perch × Nido — Authorization Console</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230C8B99' stroke-width='2'%3E%3Cpath d='M4 20V10a8 8 0 0 1 16 0v10'/%3E%3Cpath d='M4 20h16'/%3E%3Ccircle cx='12' cy='10' r='2.4'/%3E%3C/svg%3E" />
<link rel="stylesheet" href="/src/styles.css" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
26 changes: 26 additions & 0 deletions examples/perch-authz-console/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "perch-authz-console",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"build:pages": "tsc && vite build --base=/${REPO_NAME:-nido}/",
"build:preview": "tsc && vite build --base=./",
"preview": "vite preview",
"typecheck": "tsc --noEmit",
"test:e2e": "playwright test"
},
"dependencies": {
"@creit.tech/stellar-wallets-kit": "^2.2.0",
"@nidohq/testkit": "*",
"@noble/hashes": "^2.2.0"
},
"devDependencies": {
"@playwright/test": "^1.50.0",
"typescript": "~5.9.3",
"vite": "^7.3.1",
"vite-plugin-node-polyfills": "^0.25.0"
}
}
18 changes: 18 additions & 0 deletions examples/perch-authz-console/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
fullyParallel: true,
reporter: [['list']],
use: {
baseURL: 'http://localhost:5177',
viewport: { width: 1200, height: 1400 },
},
webServer: {
command: 'npx vite --port 5177 --strictPort',
url: 'http://localhost:5177',
reuseExistingServer: !process.env.CI,
timeout: 60_000,
},
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
});
Loading
Loading