ansible/portal-operations-backend¶
Backend plugin for authorized Portal operation dispatch and entitlement
decisions. Source: workspaces/portal-core/plugins/portal-operations-backend.
Integration¶
The ./alpha backend feature loader installs the host-owned operation,
entitlement, and health services once, then loads the backend plugin:
Contributor backends register operations through portalOperationsServiceRef.
The host dispatches operation IDs with authenticated context and current subjects,
not contributor-supplied handler URLs.
Organization and entitlement policy¶
The AAP adapter verifies authenticated identity and resolves current direct
organization and team memberships, restricted to configured Portal organizations.
Entitlement grants under portal.entitlements.grants use the adapter's canonical
lowercase organization names or '*'. A missing grant denies entitlement; a
grant does not prove membership or replace RBAC. Existing AAP superuser access
to configured organizations does not bypass grants or permissions.
The same injected resolver supplies operation contexts and entitlement decisions.
The dispatcher rejects missing or inconsistent membership context and enforces
every backend descriptor's requiredEntitlements before invoking its handler.
APME scanning declares apme.scanning. Registration and deregistration remain
available without that scanning entitlement, subject to their own permissions.
For a shared operation (organizationScope: 'shared'), any membership granted
the required entitlement enables availability. A user in Engineering and Finance
can use a shared capability granted only to Engineering, subject to operation
and resource permissions. organizations: ['*'] covers the caller's configured
memberships; it does not grant membership in other organizations.
Descriptors default to organizationScope: 'organization'. Those handlers need
one validated organizationId, and organization-scoped entitlements must grant
that organization. organizationIds can contain multiple memberships, but the
dispatcher does not choose the first. There is no organization selector in this
flow. Shared Git repository operations do not choose a storage tenant for
organization-specific plugin state.
Minimal AAP policy¶
With Engineering already configured in the AAP provider:
Multi-organization AAP policy¶
Keep your existing AAP connection configuration and configure organization scope and grants as follows:
catalog:
providers:
rhaap:
development:
orgs: [Engineering, Finance]
multiOrgEnabled: true
portal:
entitlements:
grants:
- id: apme.scanning
organizations: [engineering, finance]
With multiOrgEnabled: true, AAP user identities use user:default/aap-user-<id>;
organization groups use ID-based names and namespaces. Authentication, scheduled
catalog sync and the extracted user provisioner use the same naming contract.
With the flag off, legacy usernames remain supported; the resolver performs an
unambiguous AAP username lookup. A failed identity or membership lookup denies
access rather than falling back to default or all organizations. Changing the
identity flag changes affected catalog references; synchronize the catalog and
sign in again after changing it.
Generic host fallback¶
Hosts without the AAP adapter can use the generic configured resolver:
portal:
organization:
id: default
entitlements:
grants:
- id: apme.scanning
organizations: [default]
This is a trusted deployment context, not an AAP membership resolver. When the
AAP adapter is installed, it uses the configured AAP organizations and verified
memberships instead of portal.organization.id.
Shared repository identity¶
Git repositories do not require an AAP organization owner. New manual entries
use catalog namespace default; catalog namespace and SCM organization do not
determine AAP memberships. Repository access still requires resource RBAC and
the handler's repository type, URL/branch, provenance and tracking checks.
Remove obsolete portal.organization.catalogMappings configuration. The former
mapping policy and ansible.io/portal-organization ownership checks are no longer
used. Existing persisted entries and annotations are not renamed, backfilled or
deleted by this change.
Frontend context endpoint¶
GET /api/portal-operations/context requires user authentication and returns
userEntityRef, userId, and either one organizationId or multiple
organizationIds. The frontend SDK normalizes these into a membership list for
display. No active organization is selected for multiple memberships. Operation
requests do not accept client-supplied organization context; the dispatcher
independently resolves it.
Interactive workflow boundaries¶
APME operation submission, approval, state/events, and remediation submission authorize trusted memberships, scanning entitlement, and catalog repository before forwarding gateway requests or resolving SCM credentials. Mutating requests additionally require the scan operation permission. Read-only state/event requests do not require that mutation permission.
This does not migrate every legacy settings route, change automatic scan policy, partition gateway storage, or revoke running jobs when a grant changes.
Troubleshooting¶
Operation denied although the action is visible: check backend descriptor requirements, registered entitlement definitions, grants for the caller's resolved memberships, operation permission, and the handler's resource checks.
User with several memberships cannot invoke an organization-specific operation: the handler requires one validated organization, not an arbitrary first member. Use shared scope only when the resource and operation are genuinely shared.
Shared repository denied: check verified AAP memberships, configured grants, operation and catalog read permissions, repository identity and tracking state. Do not add a namespace mapping or bypass resource authorization. Re-export affected dynamic consumers and restart the backend after changing contracts or policy configuration.
See NFS composition for frontend checks and portal-plugin-node for service contracts.