-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Limit access to API endpoints when using Maskinporten clients as a ServiceOwner #923
Comments
Hey, there is a way to isolate apps by using scopes in Maskinporten. So given the scenario of
If app_a requires a scope (in XACML policy) that is assigned only Maskinporten_client_a, and app_b requires a scope that is assigned only to Maskinporten_client_b then I think that does what you want. Here is example XACML: <xacml:Rule RuleId="urn:altinn:example:ruleid:1" Effect="Permit">
<xacml:Description>A rule giving user with role PRIV and the app owner [ORG] (using a Maskinporten client with the 'test:app.a' scope) the right to instantiate a instance of a given app of [ORG]/[APP]</xacml:Description>
<xacml:Target>
<xacml:AnyOf>
<xacml:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">priv</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:rolecode" 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:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">[org]</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:org" 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:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">test:app.a</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:scope" 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:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">[ORG]</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:org" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
</xacml:Match>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">[APP]</xacml:AttributeValue>
<xacml:AttributeDesignator AttributeId="urn:altinn:app" 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:3.0:function:string-equal-ignore-case">
<xacml:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">instantiate</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:AllOf>
<xacml:Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
<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> In this case, instantiation can either be done by PRIV users or an org token which also has the scope Does this work for your case? |
Unfortunately no, @martinothamar, our issue is related to being a ServiceOwner (often represented with id [org]) and scope not being checked beyond that. It is possible to describe the required behavior in a XACML policy, but currently this is not respected by the APIs (Can you confirm this, @RonnyB71?) |
All requests (that aren't hitting public endpoints) are being checked by the PEP library which uses the XACML to authorize based on current context. As far as I know there are no endpoints where we manually verify scopes, but that doesn't mean you can't do it yourself through XACML. PEP will load the So as far as I can tell
This can be made to work with a policy like above. You will still have to configure the scopes and clients correctly in Maskinporten (meaning only client A gets scope A).
These scopes don't do much by default, but here's nothing stopping us from referring to these in the XACML policy. The only place I know of where the presence of these scopes are enforced is the |
What you describe here is exactly how we expected things to work. We were told otherwise and this is why we got worried. We'll try to set up some real testcases, in order to verify that this is indeed working this way. Thanks for the clarifications! 💪 💯 |
Description
As a ServiceOwner, we are in need of limiting the scope on a system level, i.e limit the access only to the API endpoints exposed for App(s) that the used Maskinporten client has been configured for.
Example:
System A has Maskinporten_client_A setup with policies that only allows access to APIs of specified Apps in Altinn
System B has Maskinporten_client_B setup with policies that only allows access to APIs of specified Apps in Altinn
When using Maskinporten_client_A, API access should be limited to Apps in Altinn as specified in policies
When using Maskinporten_client_B, API access should be limited to Apps in Altinn as specified in policies
If System A tries to Instantiate an App outside of the specified policies of the Maskinporten client, the request should be denied
If System B tries to Instantiate an App outside of the specified policies of the Maskinporten client, the request should be denied
The request adheres to the principles of Zero Trust, that we believe should be followed.
Currently, either client would allow access to all apps owned by the ServiceOwner.
When we, as a ServiceOwner, using a Maskinporten client to request access to use the Altinn Apps APIs, scope is verified against the policy file as [org]. In other words the organisation is authenticated, without any further scope limitations.
Currently the required (only) scopes are:
altinn:serviceowner/instances.read
altinn:serviceowner/instances.write
Current functionality is also described here: https://docs.altinn.studio/api/authentication/maskinporten/
Additional Information
This request might relate to
Altinn/altinn-authentication#500
Altinn/app-template-dotnet#23
The text was updated successfully, but these errors were encountered: