snulbug 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {snulbug-0.2.1 → snulbug-0.2.3}/CHANGELOG.md +26 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/PKG-INFO +4 -2
- {snulbug-0.2.1 → snulbug-0.2.3}/README.md +3 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/SECURITY.md +10 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/auth-providers.md +5 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/devcontainers.md +2 -2
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-auth-recipes.md +112 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-proxy.md +4 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-share.md +88 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/release.md +4 -3
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/.devcontainer/devcontainer.json +1 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/features/snulbug/README.md +1 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/features/snulbug/devcontainer-feature.json +1 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/pyproject.toml +1 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/__init__.py +3 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/auth_recipes.py +114 -7
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/share.py +22 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/leases.py +227 -6
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_auth.py +8 -1
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/proxy.py +133 -5
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/redaction.py +3 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/share.py +261 -6
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/share_console.py +67 -0
- snulbug-0.2.3/tests/fixtures/pocket_id/README.md +19 -0
- snulbug-0.2.3/tests/fixtures/pocket_id/oauth.json +66 -0
- snulbug-0.2.3/tests/test_automation_invites.py +538 -0
- snulbug-0.2.3/tests/test_pocket_id_auth.py +345 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/.gitignore +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/CODE_OF_CONDUCT.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/CONTRIBUTING.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/LICENSE +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/actions.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/aws-mcp.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/bundles.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/ci-policy-gates.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/comparison.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/credential-brokers.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/discovery-providers.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/event-sink-providers.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/evidence-exporters.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/getting-started.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/lua-policy-dsl.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/lua-request-api.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-client-recipes.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-evidence.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-fabric.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-gateway.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-guide.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-impact.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-learn.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-policy.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-presets.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-protocol.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-recorder.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/mcp-schemas.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/ngrok-end-to-end.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/policy-deny-backoff.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/quickstart.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/roadmap.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/security-model.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/share-doctor-checks.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/state.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/tool-catalog-projection.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/tool-risk-analyzers.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/tunnel-providers.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/docs/upstream-transports.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/auth_claim_patterns/.gitignore +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/auth_claim_patterns/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/auth_claim_patterns/ci-workload-identity.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/auth_claim_patterns/group-gated-tools.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/auth_claim_patterns/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/auth_claim_patterns/tenant-isolation.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/basic/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/basic/app.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/fixtures/duplicate-delivery.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/fixtures/first-delivery.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/snapshots/duplicate.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/idempotency.snulbug/snapshots/empty.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/fixtures/allowed-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/fixtures/blocked-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/fixtures/unauthenticated.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/bundles/mcp-gateway.snulbug/snapshots/empty.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/mcp-client.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/mock_mcp_server.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/snulbug.env-gateway.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/snulbug.local-gateway.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/app.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/policies/acme.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/policies/default.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/policies/globex.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/requests/acme-invalid.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/requests/acme-valid.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/requests/globex-sandbox.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/customer_policy/requests/unknown-tenant.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/github-actions/snulbug-policy-gates.yml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/.gitignore +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/Dockerfile.gateway +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/auth/keycloak/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/auth/keycloak/auth-init.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/auth/keycloak/client-token-request.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/auth/keycloak/commands.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/auth/keycloak/snulbug.auth.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/docker-compose.yml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/get-token.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/keycloak/snulbug-demo-realm.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/mock_mcp_server.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/policy.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/requests/blocked-write-file.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/requests/read-file.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/requests/tools-list.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/keycloak_oauth_demo/snulbug.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/Dockerfile.gateway +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/Dockerfile.remote-peer +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/docker-compose.yml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/hypertele-client.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/hypertele-server.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/mcp-client.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/mock_mcp_server.js +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/mock_mcp_server.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/snulbug.facade.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_container_facade/snulbug.local.toml +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_gateway/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_gateway/app.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/.gitignore +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/requests/blocked-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/requests/safe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/requests/tools-list.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/run_demo.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/mcp_proxy_demo/upstream.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/policy_promotion/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/policy_promotion/active.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/policy_promotion/draft.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/policy_promotion/fixtures/acme-invalid.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/policy_promotion/fixtures/acme-valid.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/provider_policy_templates/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/provider_policy_templates/cloudflare-access-group-gate.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/provider_policy_templates/entra-app-role-gate.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/provider_policy_templates/github-actions-workload-gate.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/provider_policy_templates/keycloak-role-gate.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/state_replay/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/state_replay/duplicate-state.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/state_replay/idempotency.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/state_replay/request.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/app.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/policies/github.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/policies/stripe.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/policies/unknown.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/requests/github-push.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/requests/stripe-invoice.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/requests/stripe-malformed.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/examples/webhook_normalization/requests/unknown-vendor.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/features/snulbug/install.sh +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/__main__.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/assets/prism.css +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/assets/prism.js +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/auth_providers.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/auth-required.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/auth-required.snulbug/fixtures/authenticated.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/auth-required.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/auth-required.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/auth-required.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/contexts/inventory-lease.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/contexts/sandbox-change-lease.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/fixtures/data-read.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/fixtures/iam-delete-user.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/fixtures/inventory-read.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/fixtures/knowledge-search.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/fixtures/sandbox-mutation.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/aws-mcp.snulbug/snapshots/empty.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/fixtures/safe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/fixtures/unsafe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/local-dev-safe.snulbug/snapshots/empty.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/no-shell-tools.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/no-shell-tools.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/no-shell-tools.snulbug/fixtures/safe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/no-shell-tools.snulbug/fixtures/shell-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/no-shell-tools.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/no-shell-tools.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/fixtures/absolute-path.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/fixtures/allowed-path.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/fixtures/traversal-path.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/fixtures/unsafe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/project-path-allowlist.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/fixtures/safe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/fixtures/tools-list.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/fixtures/write-method.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/read-only-local-dev.snulbug/snapshots/empty.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tool-allowlist.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tool-allowlist.snulbug/fixtures/safe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tool-allowlist.snulbug/fixtures/tools-list.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tool-allowlist.snulbug/fixtures/unsafe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tool-allowlist.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tool-allowlist.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/fixtures/batch-request.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/fixtures/safe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/fixtures/unsafe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/tunnel-safe.snulbug/snapshots/empty.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/fixtures/allowed-read.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/fixtures/missing-token.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/fixtures/secret-path.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/fixtures/traversal-path.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/fixtures/unsafe-tool.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/manifest.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/builtin_presets/mcp/workspace-firewall.snulbug/policy.lua +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/bundle.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/__init__.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/common.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/evidence.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/fabric.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/policy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/rich_reports.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/rich_share.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli/schemas.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cli_helpers.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/cloudflare_access.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/codespaces.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/config.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/confirm.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/control_events.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/controller.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/credentials.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/discovery.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/events.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/evidence_exporters.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/fabric.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/fabric_control.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/fabric_members.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/fabric_runtime.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/gateway_templates.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/guide.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/http_routes.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/impact.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/inspection.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/json_schema.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/lab.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/learn.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/manifests.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_cache.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_capabilities.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_client_requests.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_completion.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_mrtr.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_parameter_headers.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_policy_bundles.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_progress.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_protocol.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_resources.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_schema_policy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_schemas.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_spec_conformance.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_stdio.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_stream.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_subscriptions.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_tasks.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/mcp_tools.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/middleware.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/policy_activation.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/policy_backoff.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/policy_review.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/presets.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/promotion.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/py.typed +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/quickstart.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/recorder.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/release_qa.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/response_policy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/runtime.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/sarif.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/scaffolds.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/schema_policy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/share_doctor.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/share_session.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/simulator.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/state.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/tool_catalog.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/tool_risk.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/tunnel.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/snulbug/upstream_transports.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/LICENSE +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/README.md +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/dependentSchemas.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/dynamicRef.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/if-then-else.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/prefixItems.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/json_schema_2020_12/unevaluatedProperties.json +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/fixtures/stdio_subscriptions.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_auth_claim_patterns.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_auth_recipes.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_cli_helpers.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_cloudflare_access.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_codespaces.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_config.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_credentials.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_customer_policy_demo.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_devcontainer_feature.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_discovery.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_events.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_evidence_exporters.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_fabric.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_fabric_controller.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_http_routes.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_json_schema.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_keycloak_oauth_demo.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_leases.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_manifests.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_cache.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_gateway_demo.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_guide.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_helpers.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_impact.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_inspection.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_lab.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_learn.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_mrtr.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_parameter_headers.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_policy_bundles.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_presets.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_progress.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_protocol.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_proxy_demo.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_quickstart.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_recorder.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_resources.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_schema_policy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_schemas.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_share.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_spec_conformance.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_stdio.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_stream.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_subscriptions.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_mcp_tools.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_middleware.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_policy_bundle.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_policy_promotion.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_policy_state.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_provider_policy_templates.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_proxy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_redaction_audit.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_release_qa.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_response_policy.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_sandbox_abuse.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_scaffolds.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_share_console.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_state_snapshots.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_tool_catalog.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_tool_risk.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_tunnel_audit.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_tunnel_doctor.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_tunnel_init.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_upstream_transports.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_webhook_normalization_demo.py +0 -0
- {snulbug-0.2.1 → snulbug-0.2.3}/tests/test_webhooks.py +0 -0
|
@@ -6,6 +6,32 @@ The format is based on Keep a Changelog, and this project follows semantic versi
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.3] - 2026-10-18
|
|
10
|
+
|
|
11
|
+
Add Pocket ID setup through the existing OAuth provider and lease machinery.
|
|
12
|
+
|
|
13
|
+
- Added `share auth init --provider pocket-id` with resource-bound API permissions, deny-by-default scope maps, PKCE/CIMD registration instructions, automation guidance, and lease-aware doctor commands.
|
|
14
|
+
- Extended auth doctor to check exact issuer metadata identity, advertised PKCE S256, and CIMD availability without claiming access to private provider grants or allowlists.
|
|
15
|
+
- Added synthetic RS256 user/bot token fixtures, rejection and JWKS rotation tests, and existing auth conformance-pack coverage; documented setup and identity-claim limitations.
|
|
16
|
+
|
|
17
|
+
Pocket ID live passkey/client interoperability remains unverified. This release
|
|
18
|
+
does not add browser console login or authentication to HTTP mounts. No change
|
|
19
|
+
to the default MCP protocol version or the experimental profile's limitations.
|
|
20
|
+
|
|
21
|
+
## [0.2.2] - 2026-10-16
|
|
22
|
+
|
|
23
|
+
Support always-on MCP bots with renewable automation invites, without introducing
|
|
24
|
+
a separate permission or approval system.
|
|
25
|
+
|
|
26
|
+
- Added renewable automation invites using the existing backing lease, with bounded consumer renewal/restart recovery, rotating access tokens, identity bindings, persistent usage budgets, and console/CLI setup snippets.
|
|
27
|
+
- Serialized lease mutations across local workers so renewal, revocation, cleanup, and concurrent call consumption cannot overwrite each other's state.
|
|
28
|
+
- Added renewal visibility and refresh-stable invite forms in the web console, secret-safe renewal audit events, and share closeout that revokes invites as well as the session lease.
|
|
29
|
+
|
|
30
|
+
Automation renewal is opt-in. Access leases remain short-lived; the owner's
|
|
31
|
+
renewal authorization has a separate hard expiry. Clients must adopt refreshed
|
|
32
|
+
lease headers, and revocation or exhausted budgets prevent recovery. No change
|
|
33
|
+
to the default MCP protocol version or the experimental profile's limitations.
|
|
34
|
+
|
|
9
35
|
## [0.2.1] - 2026-10-15
|
|
10
36
|
|
|
11
37
|
Expose web applications and APIs alongside MCP through one gateway and ngrok tunnel.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: snulbug
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A local-dev MCP policy proxy with Lua policies, replay logs, and learned least-privilege bundles
|
|
5
5
|
Project-URL: Homepage, https://github.com/nahuaque/snulbug
|
|
6
6
|
Project-URL: Repository, https://github.com/nahuaque/snulbug
|
|
@@ -63,6 +63,8 @@ It gives you a tight loop for agent-tool safety:
|
|
|
63
63
|
- review MCP-native capability requests and approve them into normal task leases
|
|
64
64
|
- use task-scoped leases for temporary tool/path grants, optionally bound to
|
|
65
65
|
OAuth subject, tenant, client, group, issuer, or auth profile
|
|
66
|
+
- give always-on bots [renewable automation invites](docs/mcp-share.md#renewable-automation-invites)
|
|
67
|
+
with short-lived leases, consumer renewal, and restart recovery
|
|
66
68
|
- turn OAuth identity into MCP-specific tool permissions
|
|
67
69
|
- pin facade upstream identity with signed manifests
|
|
68
70
|
|
|
@@ -466,7 +468,7 @@ Workflow:
|
|
|
466
468
|
- optional OAuth protected-resource mode with JWT/JWKS, token introspection, DPoP validation, and MCP auth challenges
|
|
467
469
|
- OAuth scope-to-MCP method/tool mapping for least-privilege public shares
|
|
468
470
|
- OAuth resource/audience drift checks for tunnel-safe public shares
|
|
469
|
-
- generated auth setup flows for Keycloak, Auth0, Okta, Entra, Cloudflare Access, and GitHub OIDC
|
|
471
|
+
- generated auth setup flows for Keycloak, Pocket ID, Auth0, Okta, Entra, Cloudflare Access, and GitHub OIDC
|
|
470
472
|
- composable OAuth + auth-bound task lease + Lua policy access decisions
|
|
471
473
|
- anti-passthrough credential brokering so caller OAuth tokens stop at snulbug
|
|
472
474
|
- learned least-privilege bundles from observed traffic
|
|
@@ -20,6 +20,8 @@ It gives you a tight loop for agent-tool safety:
|
|
|
20
20
|
- review MCP-native capability requests and approve them into normal task leases
|
|
21
21
|
- use task-scoped leases for temporary tool/path grants, optionally bound to
|
|
22
22
|
OAuth subject, tenant, client, group, issuer, or auth profile
|
|
23
|
+
- give always-on bots [renewable automation invites](docs/mcp-share.md#renewable-automation-invites)
|
|
24
|
+
with short-lived leases, consumer renewal, and restart recovery
|
|
23
25
|
- turn OAuth identity into MCP-specific tool permissions
|
|
24
26
|
- pin facade upstream identity with signed manifests
|
|
25
27
|
|
|
@@ -423,7 +425,7 @@ Workflow:
|
|
|
423
425
|
- optional OAuth protected-resource mode with JWT/JWKS, token introspection, DPoP validation, and MCP auth challenges
|
|
424
426
|
- OAuth scope-to-MCP method/tool mapping for least-privilege public shares
|
|
425
427
|
- OAuth resource/audience drift checks for tunnel-safe public shares
|
|
426
|
-
- generated auth setup flows for Keycloak, Auth0, Okta, Entra, Cloudflare Access, and GitHub OIDC
|
|
428
|
+
- generated auth setup flows for Keycloak, Pocket ID, Auth0, Okta, Entra, Cloudflare Access, and GitHub OIDC
|
|
427
429
|
- composable OAuth + auth-bound task lease + Lua policy access decisions
|
|
428
430
|
- anti-passthrough credential brokering so caller OAuth tokens stop at snulbug
|
|
429
431
|
- learned least-privilege bundles from observed traffic
|
|
@@ -59,6 +59,16 @@ Limits:
|
|
|
59
59
|
schemas pass through unless your Lua policy blocks them separately.
|
|
60
60
|
- Leases are bearer-style capabilities. Store `leases.json` locally, rotate or
|
|
61
61
|
revoke leases after sharing, and prefer short TTLs for public tunnel use.
|
|
62
|
+
- Renewable automation invites add a separate, reusable renewal credential with
|
|
63
|
+
an owner-set hard deadline. Treat it as a long-lived bot secret: theft together
|
|
64
|
+
with the required gateway authentication permits recovery within the approved
|
|
65
|
+
capability and call-budget bounds until revocation or expiry. It does not
|
|
66
|
+
grant console access. Renewal retains the existing lease's usage count and
|
|
67
|
+
identity bindings; revocation disables recovery. Access-token rotation has a
|
|
68
|
+
bounded overlap of at most 30 seconds. Lease operations are serialized on the
|
|
69
|
+
local lease file; independent gateway hosts must not treat copied JSON stores
|
|
70
|
+
as a shared revocation authority. The owner console's invite secret store
|
|
71
|
+
contains plaintext setup credentials and must remain private.
|
|
62
72
|
|
|
63
73
|
### Malicious or compromised MCP server
|
|
64
74
|
|
|
@@ -5,9 +5,13 @@ snulbug has a small auth provider extension point for two related jobs:
|
|
|
5
5
|
- generate `snulbug mcp share auth init --provider ...` setup recipes
|
|
6
6
|
- map provider-specific token claims into `context.auth.provider.*` for Lua policy helpers
|
|
7
7
|
|
|
8
|
-
Built-ins cover Keycloak, Auth0, Okta, Entra, Cloudflare Access, and GitHub
|
|
8
|
+
Built-ins cover Keycloak, Pocket ID, Auth0, Okta, Entra, Cloudflare Access, and GitHub
|
|
9
9
|
Actions OIDC. External providers can register the same surface from Python.
|
|
10
10
|
|
|
11
|
+
The [Pocket ID recipe](mcp-auth-recipes.md#pocket-id) uses standard verified
|
|
12
|
+
subject/client identity and API scopes. It does not invent provider claims or
|
|
13
|
+
retrieve identity claims from ID tokens/userinfo during MCP requests.
|
|
14
|
+
|
|
11
15
|
```python
|
|
12
16
|
from collections.abc import Mapping
|
|
13
17
|
from typing import Any
|
|
@@ -10,8 +10,8 @@ servers with a shared control plane.
|
|
|
10
10
|
```json
|
|
11
11
|
{
|
|
12
12
|
"features": {
|
|
13
|
-
"ghcr.io/nahuaque/snulbug/features/snulbug:0.2.
|
|
14
|
-
"version": "0.2.
|
|
13
|
+
"ghcr.io/nahuaque/snulbug/features/snulbug:0.2.3": {
|
|
14
|
+
"version": "0.2.3",
|
|
15
15
|
"mode": "member-agent",
|
|
16
16
|
"policy_profile": "tunnel-safe",
|
|
17
17
|
"registry": "redis://redis:6379/0",
|
|
@@ -37,6 +37,7 @@ snulbug mcp share auth recipe \
|
|
|
37
37
|
Supported providers:
|
|
38
38
|
|
|
39
39
|
- `keycloak`
|
|
40
|
+
- `pocket-id`
|
|
40
41
|
- `auth0`
|
|
41
42
|
- `okta`
|
|
42
43
|
- `okta-xaa`
|
|
@@ -51,6 +52,8 @@ provider can be validated against a live dev account:
|
|
|
51
52
|
|
|
52
53
|
- Keycloak: runnable Docker Compose demo in
|
|
53
54
|
[`examples/keycloak_oauth_demo`](../examples/keycloak_oauth_demo/README.md).
|
|
55
|
+
- Pocket ID: generated setup and synthetic RS256 token/discovery fixtures are
|
|
56
|
+
covered; a live passkey login or real-client demo has not been validated.
|
|
54
57
|
- Auth0: generated setup recipe is available; live provider demo forthcoming.
|
|
55
58
|
- Okta: generated setup recipe is available; live provider demo forthcoming.
|
|
56
59
|
- Okta XAA / MCP Enterprise-Managed Authorization: generated setup recipe is
|
|
@@ -137,9 +140,92 @@ Lua identity policy to constrain the workflow.
|
|
|
137
140
|
|
|
138
141
|
## Provider Notes
|
|
139
142
|
|
|
143
|
+
### Keycloak
|
|
144
|
+
|
|
140
145
|
Keycloak often needs an explicit audience mapper so access tokens contain the
|
|
141
146
|
MCP public URL in `aud`.
|
|
142
147
|
|
|
148
|
+
### Pocket ID
|
|
149
|
+
|
|
150
|
+
Use Pocket ID as the external issuer, with snulbug as its protected API:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
snulbug mcp share auth init \
|
|
154
|
+
--provider pocket-id \
|
|
155
|
+
--url https://share.example.com/mcp \
|
|
156
|
+
--issuer https://id.example.com \
|
|
157
|
+
--client-id "$POCKET_ID_CLIENT_ID"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Use the actual client ID from Pocket ID, not the client's display name. Omit
|
|
161
|
+
`--client-id` to generate instructions before registering a client.
|
|
162
|
+
|
|
163
|
+
This writes `.snulbug/auth/pocket-id/` with the normal five setup files. Review
|
|
164
|
+
the generated README and merge `snulbug.auth.toml` into your existing share
|
|
165
|
+
config; the overlay is not a standalone upstream/policy configuration. From a
|
|
166
|
+
source checkout, prefix these commands with `uv run`.
|
|
167
|
+
|
|
168
|
+
In Pocket ID, create an **API** with resource `https://share.example.com/mcp`,
|
|
169
|
+
then add the permission keys listed in the generated setup. Grant those
|
|
170
|
+
permissions to the MCP client under **User-delegated access**. Public clients
|
|
171
|
+
use authorization code with PKCE S256 and their exact callback URLs. The client
|
|
172
|
+
requests `resource=https://share.example.com/mcp` and `openid` plus the API
|
|
173
|
+
permissions. It sends the resulting **access token**, not its ID token, to
|
|
174
|
+
snulbug. See [Pocket ID APIs and permissions](https://pocket-id.org/docs/guides/apis).
|
|
175
|
+
|
|
176
|
+
`--scope` can narrow the generated permission set. `mcp:connect` is always
|
|
177
|
+
required. Default tool selectors are examples (`filesystem.read_file` and
|
|
178
|
+
`git.status`); change them to match discovered tool names. Custom permissions
|
|
179
|
+
start with empty selector lists, which grant no MCP actions until mapped. A
|
|
180
|
+
connect-only configuration does not implicitly grant all tools. Identity scopes
|
|
181
|
+
such as `openid` are not API permission keys; the client request adds `openid`
|
|
182
|
+
automatically.
|
|
183
|
+
|
|
184
|
+
For CIMD clients, Pocket ID requires an explicit metadata-document URL allowlist
|
|
185
|
+
and a separate API permission grant. Prefer exact metadata URLs. The API-wide
|
|
186
|
+
metadata-client grant applies to future allowed clients too; it is not a grant
|
|
187
|
+
to just one client. Manual registration remains supported, so disabled CIMD is
|
|
188
|
+
not a doctor failure. See [Pocket ID client metadata](https://pocket-id.org/docs/guides/client-id-metadata-documents).
|
|
189
|
+
|
|
190
|
+
Keep `lease_required = true` and give the consumer its `x-snulbug-lease` header.
|
|
191
|
+
Automation uses a separate confidential client with **Client access (M2M)**,
|
|
192
|
+
resource-bound API permissions, and an identity-bound renewable invite. Pocket
|
|
193
|
+
ID token acquisition/refresh and snulbug lease renewal remain separate consumer
|
|
194
|
+
operations. No client secret or refresh token belongs in the gateway config.
|
|
195
|
+
|
|
196
|
+
Do not assume Pocket ID groups or custom tenant claims are present in API access
|
|
197
|
+
tokens: profile/custom claims are documented for ID tokens/userinfo. This recipe
|
|
198
|
+
uses subject/client identity, scopes, and leases, without a new claim mapper or
|
|
199
|
+
userinfo fetch. Inspect actual API tokens before adding claim-dependent Lua.
|
|
200
|
+
See [Pocket ID scopes and claims](https://pocket-id.org/docs/guides/scopes-and-claims).
|
|
201
|
+
|
|
202
|
+
After starting the share, verify it with the existing doctor:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
snulbug mcp share auth doctor \
|
|
206
|
+
--config .snulbug/shares/my-share/snulbug.toml \
|
|
207
|
+
--url https://share.example.com/mcp \
|
|
208
|
+
--token "$ACCESS_TOKEN" \
|
|
209
|
+
--header "x-snulbug-lease: $SNULBUG_LEASE"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Doctor checks public resource/audience alignment, metadata issuer identity,
|
|
213
|
+
PKCE S256 when authorization code is advertised, reachable JWKS, and scope-map
|
|
214
|
+
tool targets. It reports CIMD advertisement but cannot inspect Pocket ID's
|
|
215
|
+
private API grants or allowlist. Global issuer `scopes_supported` is not proof
|
|
216
|
+
that a particular API permission was granted. Prove sample tokens, discovered
|
|
217
|
+
schemas, and recorded evidence with the existing [auth conformance pack](#auth-conformance-pack).
|
|
218
|
+
Token checks cover authentication on initialization; tool-scope behavior also
|
|
219
|
+
needs recorded/replayed calls. DPoP stays optional pending issuer/client testing.
|
|
220
|
+
|
|
221
|
+
Use stable HTTPS issuer and public resource URLs. If a tunnel URL changes,
|
|
222
|
+
register a replacement Pocket ID API resource, grant it to the client, and align
|
|
223
|
+
the snulbug configuration rather than accepting client-ID audiences. Pocket ID
|
|
224
|
+
API resources cannot be edited after creation. Console authentication is
|
|
225
|
+
unchanged; this recipe does not add Pocket ID console login.
|
|
226
|
+
|
|
227
|
+
### Other Providers
|
|
228
|
+
|
|
143
229
|
Auth0 should model the MCP endpoint as an API whose Identifier is the public MCP
|
|
144
230
|
URL, then issue access tokens for that audience.
|
|
145
231
|
|
|
@@ -185,3 +271,29 @@ For provider-specific Lua helper patterns, see
|
|
|
185
271
|
[`examples/provider_policy_templates`](../examples/provider_policy_templates/README.md).
|
|
186
272
|
It includes copyable Keycloak role gates, Entra app-role gates, GitHub Actions
|
|
187
273
|
workload gates, and Cloudflare Access group gates.
|
|
274
|
+
|
|
275
|
+
## Auth Conformance Pack
|
|
276
|
+
|
|
277
|
+
After recording authenticated MCP calls and discovering schemas, use the existing
|
|
278
|
+
auth conformance workflow for any OAuth provider. Set `ACCESS_TOKEN` to a valid
|
|
279
|
+
API access token and `WRONG_AUDIENCE_TOKEN` to a token for a different resource
|
|
280
|
+
or a client-bound ID token. Keep both in the environment, not checked-in files:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
snulbug mcp share auth conformance generate \
|
|
284
|
+
--config .snulbug/shares/my-share/snulbug.toml \
|
|
285
|
+
--url https://share.example.com/mcp \
|
|
286
|
+
--schema-catalog schemas.json \
|
|
287
|
+
--log audit.jsonl --kind audit \
|
|
288
|
+
--token-env valid=ACCESS_TOKEN \
|
|
289
|
+
--denied-token-env wrong-audience=WRONG_AUDIENCE_TOKEN \
|
|
290
|
+
--output-dir .snulbug/auth-conformance
|
|
291
|
+
|
|
292
|
+
snulbug mcp share auth conformance run .snulbug/auth-conformance \
|
|
293
|
+
--header "x-snulbug-lease: $SNULBUG_LEASE"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Use your actual schema/audit paths. The pack stores token environment references,
|
|
297
|
+
config/schema fingerprints, and evidence summaries, not raw sample tokens. Run
|
|
298
|
+
with `--no-live-checks` for offline validation; this does not prove live login,
|
|
299
|
+
private issuer grants, or client interoperability.
|
|
@@ -920,6 +920,10 @@ snulbug mcp evidence impact traces/session.jsonl --lease leases.json --report-ou
|
|
|
920
920
|
In facade mode, leases use the client-facing tool name, such as
|
|
921
921
|
`files.read_file` or `git.status`.
|
|
922
922
|
|
|
923
|
+
For unattended consumers, [renewable automation invites](mcp-share.md#renewable-automation-invites)
|
|
924
|
+
extend the same task lease with bounded consumer renewal and restart recovery.
|
|
925
|
+
They retain the existing Lua, OAuth identity, revocation, and call-budget checks.
|
|
926
|
+
|
|
923
927
|
## Tool Schema Firewall
|
|
924
928
|
|
|
925
929
|
When `schema_validation = true`, snulbug learns each MCP tool's `inputSchema`
|
|
@@ -123,6 +123,94 @@ traffic is observed. The table records evidence source, confidence, risk level,
|
|
|
123
123
|
categories, and signals such as command-capable arguments, network/path
|
|
124
124
|
arguments, destructive annotations, and open argument schemas.
|
|
125
125
|
|
|
126
|
+
## Renewable Automation Invites
|
|
127
|
+
|
|
128
|
+
For an always-on bot, enable **Renewable automation invite** in the console's
|
|
129
|
+
Invites tab, or extend the normal invite command:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
snulbug mcp share invite create .snulbug/shares/my-share \
|
|
133
|
+
--recipient nightly-bot --task "Inspect project" \
|
|
134
|
+
--capability project_readonly \
|
|
135
|
+
--renewable --ttl 30m --renewal-ttl 7d
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`--ttl` controls the short-lived access lease. `--renewal-ttl` is the owner's
|
|
139
|
+
hard authorization deadline, measured from invite creation, not each renewal.
|
|
140
|
+
The backing lease keeps its ID, capabilities, identity bindings, usage count,
|
|
141
|
+
and total `--max-calls` budget. Renewal does not approve policy changes or
|
|
142
|
+
replenish an exhausted budget. Use the existing Lua rate limits for recurring
|
|
143
|
+
request limits; this is not a new daily quota system.
|
|
144
|
+
|
|
145
|
+
The setup packet includes a renewal credential, a curl command, and a Python
|
|
146
|
+
integration example. Store the renewal credential as a bot secret, separately
|
|
147
|
+
from the short-lived `x-snulbug-lease` token. It is reusable until its deadline
|
|
148
|
+
or revocation, is not an OAuth refresh token, and cannot administer the console
|
|
149
|
+
or create other invites. It is shown only through the existing owner CLI or
|
|
150
|
+
secret-gated console. Protect the share directory and its `invite-secrets.json`.
|
|
151
|
+
|
|
152
|
+
Consumers use ordinary HTTPS against the **same MCP URL**, so ngrok and other
|
|
153
|
+
generated tunnel routes need no additional public endpoint:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
export SNULBUG_MCP_URL="https://your-tunnel.example/mcp"
|
|
157
|
+
export SNULBUG_INVITE_ID="invite_..."
|
|
158
|
+
export SNULBUG_RENEWAL_TOKEN="sbr_..."
|
|
159
|
+
# Set SNULBUG_BEARER_TOKEN to the bearer token from the invite packet.
|
|
160
|
+
curl --fail-with-body -sS "$SNULBUG_MCP_URL" \
|
|
161
|
+
-H "Authorization: Bearer ${SNULBUG_BEARER_TOKEN}" \
|
|
162
|
+
-H "x-snulbug-renewal: ${SNULBUG_RENEWAL_TOKEN}" \
|
|
163
|
+
-H 'Content-Type: application/json' \
|
|
164
|
+
-H 'Accept: application/json, text/event-stream' \
|
|
165
|
+
-d "{\"jsonrpc\":\"2.0\",\"id\":\"renew\",\"method\":\"snulbug/lease/renew\",\"params\":{\"invite_id\":\"${SNULBUG_INVITE_ID}\"}}"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`snulbug/lease/renew` is a snulbug JSON-RPC extension, not a standard MCP method
|
|
169
|
+
or an upstream tool. Its only parameter is `invite_id`; the consumer cannot
|
|
170
|
+
choose a longer TTL, larger budget, or different capabilities. The gateway
|
|
171
|
+
terminates the request without forwarding the renewal credential upstream.
|
|
172
|
+
Errors use `error.data.reason_code`, even when the HTTP status is 200.
|
|
173
|
+
|
|
174
|
+
On success, `result.headers` contains the current lease header;
|
|
175
|
+
`result.lease.expires_at` and `result.lease.renewal.renew_after` tell the bot
|
|
176
|
+
when to refresh its MCP client's headers. Call again at `renew_after`, with
|
|
177
|
+
jitter and backoff for network failures. Retries inside the same lease window
|
|
178
|
+
return the same access token. A renewal rotates it with at most 30 seconds of
|
|
179
|
+
overlap for in-flight requests, bounded by the old token's original expiry.
|
|
180
|
+
After a process restart or an expired access lease, the **same operation**
|
|
181
|
+
recovers access while the owner authorization remains valid. No old lease token
|
|
182
|
+
or installed snulbug client is required. Fixed-header clients need a refresh
|
|
183
|
+
integration; a static client configuration does not renew itself.
|
|
184
|
+
|
|
185
|
+
OAuth shares still require a valid access token obtained from the configured
|
|
186
|
+
identity provider. Bind automation invites using `--allow-issuer` plus
|
|
187
|
+
`--allow-subject` or `--allow-client-id`; optionally add `--allow-tenant`.
|
|
188
|
+
Use that access token as the renewal request's `Authorization` header and the
|
|
189
|
+
separate invite renewal credential as `x-snulbug-renewal`. Required OAuth scopes,
|
|
190
|
+
DPoP requirements, and identity bindings still apply. Tool scope maps, claim
|
|
191
|
+
policies, and Lua continue to govern every ordinary MCP tool call.
|
|
192
|
+
For DPoP-required shares, the consumer must also sign and attach a fresh proof
|
|
193
|
+
for each renewal request using its existing OAuth/DPoP client integration; the
|
|
194
|
+
plain curl/Python examples do not mint proofs or OAuth access tokens.
|
|
195
|
+
|
|
196
|
+
Revoking the invite or backing lease disables renewal and restart recovery.
|
|
197
|
+
Closing the share with its default revocation option revokes its invites too.
|
|
198
|
+
Even `invite revoke --keep-lease` revokes renewal authority; it leaves only the
|
|
199
|
+
already-issued access lease usable until expiry. Removed capability labels,
|
|
200
|
+
exhausted budgets, and expired renewal authorizations fail closed. Create a new
|
|
201
|
+
invite for a new approval; operator reactivation cannot reset a renewable lease.
|
|
202
|
+
Cleanup retains expired access leases while their renewal authorization is
|
|
203
|
+
active. The console shows authorization expiry, access expiry, next renewal,
|
|
204
|
+
and last renewal/count, and keeps setup snippets synchronized with token rotation.
|
|
205
|
+
Renewal decisions go to the existing audit/event sinks, not the Lua replay log:
|
|
206
|
+
renewing a credential is a control operation, not a simulated policy decision.
|
|
207
|
+
|
|
208
|
+
Renewal and lease consumption use the existing JSON lease store with file locks
|
|
209
|
+
and atomic replacement, including across local worker processes. Persist that
|
|
210
|
+
file and the share directory across gateway restarts. This does not introduce
|
|
211
|
+
a distributed lease database; separate hosts need a shared authority rather
|
|
212
|
+
than independent copies of `leases.json`.
|
|
213
|
+
|
|
126
214
|
## Generated files
|
|
127
215
|
|
|
128
216
|
By default, the command writes under `.snulbug/shares/share-*` and creates:
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
1. Finalize `CHANGELOG.md`, with a dated release section and upgrade notes. Keep
|
|
4
4
|
protocol preview limitations distinct from package release readiness.
|
|
5
5
|
2. Bump `version` in `pyproject.toml` and `snulbug/__init__.py`, update the
|
|
6
|
-
devcontainer feature manifest and its docs/example references
|
|
6
|
+
devcontainer feature manifest and its docs/example references (including
|
|
7
|
+
`examples/codespace_local_gateway/.devcontainer/devcontainer.json`), and run `uv lock`.
|
|
7
8
|
3. Run verification:
|
|
8
9
|
|
|
9
10
|
```bash
|
|
@@ -48,7 +49,7 @@ python -m zipfile -l dist/snulbug-*.whl
|
|
|
48
49
|
8. Install from TestPyPI in a clean environment and smoke test:
|
|
49
50
|
|
|
50
51
|
```bash
|
|
51
|
-
uvx --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ snulbug==0.2.
|
|
52
|
+
uvx --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ snulbug==0.2.3 --help
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
9. Run the manual `Publish` workflow with `repository = pypi` when the TestPyPI
|
|
@@ -56,4 +57,4 @@ uvx --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org
|
|
|
56
57
|
10. Create the GitHub release and tag after the PyPI package is available.
|
|
57
58
|
|
|
58
59
|
The `Publish` workflow uses `workflow_dispatch`, not a tag trigger. Creating or
|
|
59
|
-
pushing `v0.2.
|
|
60
|
+
pushing `v0.2.3` does not publish a package or automatically create a GitHub release.
|
{snulbug-0.2.1 → snulbug-0.2.3}/examples/codespace_local_gateway/.devcontainer/devcontainer.json
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "snulbug Codespace MCP member",
|
|
3
3
|
"features": {
|
|
4
4
|
"ghcr.io/devcontainers/features/python:1": {},
|
|
5
|
-
"ghcr.io/nahuaque/snulbug/features/snulbug:0.2.
|
|
5
|
+
"ghcr.io/nahuaque/snulbug/features/snulbug:0.2.3": {
|
|
6
6
|
"install_source": "github",
|
|
7
7
|
"github_ref": "main",
|
|
8
8
|
"mode": "member-agent",
|
|
@@ -6,7 +6,7 @@ workspace helpers for Codespaces/devcontainers.
|
|
|
6
6
|
```json
|
|
7
7
|
{
|
|
8
8
|
"features": {
|
|
9
|
-
"ghcr.io/nahuaque/snulbug/features/snulbug:0.2.
|
|
9
|
+
"ghcr.io/nahuaque/snulbug/features/snulbug:0.2.3": {
|
|
10
10
|
"install_source": "github",
|
|
11
11
|
"github_ref": "main",
|
|
12
12
|
"mode": "member-agent",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "snulbug",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"name": "snulbug",
|
|
5
5
|
"description": "Install snulbug and optional helpers for MCP policy gateways and remote fabric members in devcontainers.",
|
|
6
6
|
"documentationURL": "https://github.com/nahuaque/snulbug/blob/main/docs/devcontainers.md",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Local-dev MCP policy proxy and programmable Lua ASGI policy layer."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.2.
|
|
3
|
+
__version__ = "0.2.3"
|
|
4
4
|
|
|
5
5
|
from .auth_providers import (
|
|
6
6
|
AuthProvider,
|
|
@@ -206,6 +206,7 @@ from .leases import (
|
|
|
206
206
|
create_lease,
|
|
207
207
|
list_leases,
|
|
208
208
|
reactivate_lease,
|
|
209
|
+
renew_lease,
|
|
209
210
|
revoke_lease,
|
|
210
211
|
)
|
|
211
212
|
from .manifests import load_manifest, manifest_digest, sign_upstream_manifest, verify_upstream_manifest, write_manifest
|
|
@@ -746,6 +747,7 @@ __all__ = [
|
|
|
746
747
|
"record_audit_event",
|
|
747
748
|
"record_policy_request",
|
|
748
749
|
"reactivate_lease",
|
|
750
|
+
"renew_lease",
|
|
749
751
|
"reconcile_fabric_controller",
|
|
750
752
|
"reconcile_policy_activation",
|
|
751
753
|
"register_fabric_member",
|