One access policy from content; onboarding into Kanidm as a form
Who may do what to what was five checks in five files: `qualifies` on
a page, `requires_group`/`public` on a resource, a desk's transition
allow-list, a self_transition's email check, the automation token.
They are now compiled from content on every load into one Cedar
policy set (src/access.rs), and every server entry point asks it: open
and submit a page, read a resource, move a record, fire a self
transition, read a bucket as the automation service, extend an
invite. Each decision names the rules that granted it; refusals and
every mutation are published on portal.access.decided, and
portal.access.<site>.may answers the same question for other apps
over request-reply (proven live against uhhm's content). The policy
validates against a fixed schema, so a content shape the compiler
cannot express fails instead of granting nothing. Identity is still
Kanidm's; the browser keeps is_qualified as a rendering hint only.
`invite: {group}` on an alternative of a gated page onboards a person:
src/people.rs creates the account, records the email, adds the group
and mints a one-time credential link through Kanidm's REST API with a
service-account token (KANIDM_API_TOKEN, in idm_people_on_boarding).
The result is recorded with the answer into the runtime's
portal_invites bucket and announced on portal.people.invited. Validated:
an invite needs a gated page and required name and email fields.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
7408fa972a
commit
eeeb89b217
@@ -75,6 +75,21 @@ stream.
|
||||
it - the chain verifiably answered the alternative that leads there,
|
||||
or it hangs off an earned page by a link that records nothing. A
|
||||
page behind an answer they have not given is never offered.
|
||||
- **One access policy** (`src/access.rs`): who may do what to what is
|
||||
compiled from content on every load into a Cedar policy set - `qualifies`
|
||||
on a page, `requires_group`/`public` on a resource, a desk's transitions,
|
||||
a `self_transition` by link and email, an `invite` - and every server
|
||||
entry point asks that one policy. Decisions carry the rule ids that
|
||||
granted them; refusals and every mutation are published on
|
||||
`portal.access.decided`, and other apps ask the same question over
|
||||
request-reply on `portal.access.<site>.may`. Identity stays Kanidm's.
|
||||
- **Onboarding as a form** (`src/people.rs`): an alternative with
|
||||
`invite: {group}` on a gated page creates the person in Kanidm, records
|
||||
their email, adds them to the group and mints a one-time link to set
|
||||
their own credentials, through a service account in
|
||||
`idm_people_on_boarding` (`KANIDM_API_TOKEN`). The result lands in the
|
||||
`portal_invites` bucket for the inviter's desk and on
|
||||
`portal.people.invited` for whatever sends the mail.
|
||||
- **Business needs as a checkable spec** (in
|
||||
[uhhm/iris](https://project.uhhm.no/uhhm/iris)): a content repo may
|
||||
ship a `needs.yaml` saying who wants what, which bucket the answer
|
||||
|
||||
Reference in New Issue
Block a user