Support external event production, richer authorization model for consumption
Description
There are several cases for various forms of event production and consumption that the event component will need to support, requiring a richer model for defining authorization policies, applying to both push and pull based consumption models.
In scope
How to solve immediate "Altinn-local" needs, however some Altinn products - like data.altinn.no - are for most practical purposes considered external.
Out of scope
Details on how to deal with external arbitrary event production from orgs and / or other parties not related to Altinn. This is relevant, but has governance/management implications (eg. who should be able to register event types) that are not discussed here.
Constraints
There has been identified several production/consumption scenarios spanning different event types, these include
- ConsentRequest being approved/declined, consent being revoked
- Should be consumable for CoveredBy, OfferedBy, HandledBy - maybe org
- Enables async consent flows without polling
- Brokerservice file available
- Should be consumable for all recipients
- Access to file (broker service instance) requires service-level authorization
- Potentially huge reduction in polling load on Altinn2 ("digital eiendomshandling")
- Latency requirements - too much latency and consumers will just keep polling every second
- App published/changed/disabled
- Required for sync with Altinn2 Authorization
- Metadata, no specific need for authorization
- data.altinn.no enriched consent events
- d.a.n. utilizes Altinn Consents, but the process is abstracted from the actual consumers
- Will need to consume consent request events as detailed above (being HandledBy) and emit new events enriched with d.a.n. specific information and authorization policies
- d.a.n. Tilda-events.
- Participants in the Tilda project needs to be able to post events triggering the other participants to perform lookups in d.a.n.
- Limited list of possible producers / consumers
Functional/technical requirements include:
- The various cases should be able to be realized without custom code per event type
- Event types and corresponding authorizaton models should be data-driven, eg. registerable via some API
- Event types / authorization requirements should be agnostic to consumption models (pull/push)
- Should be able to be meaningfully represented in a standard CloudEvent model
Analysis
The paragraphs below are outdated, see https://github.com/Altinn/altinn-authorization/issues/42 and https://docs.altinn.studio/technology/architecture/capabilities/runtime/integration/events/#example-4--external-event
The hypothesis is that we should be able to associate a XACML3-policy to each event type governing how a particular event type can be produced by whom, and also who should be able to consume it. There should be a context handler in place being able to process a requests for event production, subscription creation, event polls and event pushes, making available for the PDP all relevant data needed for a authorization decision, namely the authenticated party (organization number) and any scopes presented in the access token.
The XACML policy should include rules for both reading (consumption) and writing (production). There might be need to express dynamic policies, eg. enable enforcement of payload contents based on authenticated party (to prevent "impersonation"). For instance, in the Tilda-case, the subject in the payload should perhaps be the party producing the event, eg. authenticated organization number.
Rules for matching subject should be able to target OAuth2 token claims, primarily scopes. This will allow for using Maskinporten as a central access management mechanism.
A XACML3 policy for Tilda-events might look something like this. This allows everyone with a particular scope to consume and produce events, and defines a condition referring both event payload and token claims.
<?xml version="1.0" encoding="utf-8"?>
<xacml:Policy xmlns:xsl="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xacml="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:altinn:example:policyid:1" Version="1.0" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides">
<xacml:Rule RuleId="urn:altinn:example:ruleid:1" Effect="Permit">
<xacml:Description>Allow everyone with scope altinn:data-altinn-no/tilda.read to consume events type starting with "no.altinn.data.tilda"</xacml:Description>
<xacml:Target>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-contains">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn:data-altinn-no/tilda.read</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:claim:scopes" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:starts-with">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">no.altinn.data.tilda</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:event:type" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
</xacml:Target>
</xacml:Rule>
<xacml:Rule RuleId="urn:altinn:example:ruleid:2" Effect="Permit">
<xacml:Description>A rule allowing all with scope altinn:data-altinn-no/tilda.write to produce events type starting with "no.altinn.data.tilda" where subject match consumer_org-claim in token</xacml:Description>
<xacml:Target>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-contains">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">altinn:data-altinn-no/tilda.write</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:claim:scopes" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:starts-with">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">no.altinn.data.tilda</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:event:type" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
</xacml:Match>
</xacml:AllOf>
</xacml:AnyOf>
</xacml:Target>
<xacml:Condition>
<!-- Condition stating that the "subject"-field in the event should match the authenticated org number -->
<xacml:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml:AttributeDesignator AttributeId="urn:altinn:claim:consumer-orgno" DataType="http://www.w3.org/2001/XMLSchema#string" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" MustBePresent="false" />
<xacml:AttributeDesignator AttributeId="urn:altinn:event:subject" DataType="http://www.w3.org/2001/XMLSchema#string" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" MustBePresent="false" />
</xacml:Apply>
</xacml:Condition>
</xacml:Rule>
</xacml:Policy>
To be determined
- Is it possible to cover all functional requirements for both production and consumption with XACML3 policies?
- How can we make sure any event type can support both consumption models?
- Authorization can be checked upon subscription - do we need to check scopeaccess via Samarbeidsportalen-APIs before pushing events? Shouldn't long-term authorizations be right delegations in Altinn?
- What are meaningful values of
subjectandsourcein all cases? - What additional metadata do we need to store for a particular event type besides a policy?
- What changes are required in the context handler implementation?
- What changes are required in the PDP?
- What APIs for registering/administratiing event types and corresponding policies should be created?
Tasks
- [ ] Is this issue labeled with a correct area label?
- [ ] QA has been done