Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ auth:
# see https://backstage.io/docs/auth/ to learn about auth providers
providers:
# See https://backstage.io/docs/auth/guest/provider
guest: {}
guest:
userEntityRef: user:default/guest

scaffolder:
# see https://backstage.io/docs/features/software-templates/configuration for software template options
Expand Down
34 changes: 34 additions & 0 deletions docs/demo-baseline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Demo baseline

This page states what a visitor gets in the public demo. It describes the configuration in this repository, not a wishlist.

## Sign-in options

The sign-in page offers three providers, wired in `packages/app/src/App.tsx`.

- Guest. No account needed. This is the demo path.
- GitHub. Needs the production GitHub OAuth and app credentials.
- GitLab. Needs the production GitLab token.

## What a guest can do

Guest signs in as `user:default/guest`. The entity is defined in `examples/users/guest.yaml` and belongs to the `readers` group in `examples/groups/readers.yaml`.

With `permission.enabled: true`, the policy in `plugins/permission-backend-module-default/src/module.ts` gives `readers` read access only. A guest can browse the catalog, read TechDocs, use search, open the API explorer, view the catalog graph and browse the showcase and software templates.

## What a guest cannot do

A guest cannot create, update or delete catalog entities, cannot run scaffolder templates, and cannot cancel scaffolder tasks. Those actions need the `developers` group in `examples/groups/developers.yaml`. The `admins` group in `examples/groups/admins.yaml` exists for administrative membership and does not on its own grant extra policy rules today.

Template cards are safe for a guest to open and read. Submitting one will be denied by the permission policy.

## Configuration behind this

- `app-config.yaml` sets the guest `userEntityRef` to `user:default/guest` for local development.
- `app-config.production.yaml` sets the same reference and adds `dangerouslyAllowOutsideDevelopment: true`, which is required for guest access outside development. Treat a public deployment as read-only for visitors on that basis.
- Local development uses an in-memory SQLite database, so catalog changes made locally do not survive a restart. That is fine for trying the portal and is not a shared demo database.

## Known limits

- Signed-in GitHub and GitLab users only get write access if their catalog user belongs to `developers`. Membership is managed in the catalog entities, not in the OAuth provider.
- The demo data under `examples/` is sample data. It proves the portal surfaces work and is not real service ownership data.
11 changes: 11 additions & 0 deletions examples/groups/admins.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
name: admins
description: Administrative access group
spec:
type: team
profile:
displayName: Admins
email: admins@echohello.example.com
children: []
11 changes: 11 additions & 0 deletions examples/groups/developers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
name: developers
description: Create, update and delete access group for signed-in developers
spec:
type: team
profile:
displayName: Developers
email: developers@echohello.example.com
children: []
11 changes: 11 additions & 0 deletions examples/groups/readers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
name: readers
description: Read-only access group used by the guest demo user
spec:
type: team
profile:
displayName: Readers
email: readers@echohello.example.com
children: []
10 changes: 10 additions & 0 deletions examples/users/guest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
name: guest
description: Guest demo user with read-only access
spec:
profile:
displayName: Guest
email: guest@echohello.example.com
memberOf: [readers]
1 change: 1 addition & 0 deletions mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ site_name: echoHello Backstage

nav:
- index.md
- demo-baseline.md
- auth.md
- customization.md
- tracking.md
Expand Down
32 changes: 32 additions & 0 deletions plugins/permission-backend-module-default/src/module.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,38 @@ describe('policy', () => {
expect(decision.result).toBe(AuthorizeResult.DENY);
});

test('allows the guest demo user to read', async () => {
const request = createRequest('example.permission', {
action: 'read',
});
const user = createUser('guest', ['readers']);

const decision = await policy.handle(request, user);

expect(decision.result).toBe(AuthorizeResult.ALLOW);
});

test.each(['create', 'update', 'delete'] as const)(
'denies the guest demo user the %s action',
async action => {
const request = createRequest('example.permission', { action });
const user = createUser('guest', ['readers']);

const decision = await policy.handle(request, user);

expect(decision.result).toBe(AuthorizeResult.DENY);
},
);

test('denies the guest demo user scaffolder actions', async () => {
const request = createRequest('scaffolder.action.execute');
const user = createUser('guest', ['readers']);

const decision = await policy.handle(request, user);

expect(decision.result).toBe(AuthorizeResult.DENY);
});

test('denies permission for unknown actions', async () => {
const request = createRequest('example.permission', {
action: undefined,
Expand Down
Loading