We have an Identity Provider User registry, and a SOAP Web Service for applications to read/write user profiles. Now we plan to add a SCIM interface as well.
We find that Core User schema covers the basic set of attributes, however our existing system has a different naming convention for the same attributes.
For example, say USERTELEPHONENUMBER, USERSTREETADDR1 and so on.
Considering large number of applications already using this naming convention, we would like to continue the same with SCIM 2.0.
Given that we can extend the Core User schema,
1) Can we opt not using any attributes from Core schema ? If the payload includes these attributes, can we simply ignore them on the server side, and process only custom schema attributes ?
An example User document -
{
"schemas": [ "urn:scim:schemas:core:2.0:User",
urn:scim:schemas:extension:customattrs:2.0:User"],
"id": "2819c223-7f76-453a-919d-413861904646",
"urn:scim:schemas:extension:customattrs:2.0:User": {
"USERFIRSTNAME": "fname",
"USERLASTNAME": "lname",
"USERTELEPHONENUMBER": "1231231234
}
}
2) We can define a new resource itself and define a new core schema.
Which of these options would be a cleaner way ?
If you don't plan to use the core schemas, why use SCIM at all?
SCIM strongly discourage having multiple attributes that mean the same thing.
I would suggest that you create a mapping between your attributes and the SCIM core (and enterprise extension) attributes. If there are anything that does not map to the those 2 schemas, you should create an extension.
I think what you need is a mapping between scim core schema attributes and your existing system attributes. As you have said both the scim core schema and your existing system attributes share the same meaning, you should not redefine those attributes in the extension. That is strongly discouraged by scim specification.(https://www.rfc-editor.org/rfc/rfc7643#section-3.3)
Schema extensions SHOULD avoid redefining any attributes defined in
this specification and SHOULD follow conventions defined in this
specification.
However if you a have additional attributes in your existing system, you may define them in the extension.
If you have a decoupled scim implementation like WSO2 Charon (https://docs.wso2.com/display/IS450/Implementing+SCIM+with+Charon) I suggest you to have separate layer underneath the scim implementation layer to do the necessary mapping of the attributes before they are used in any business logic. But that is basically depends on your implementation.
Related
What are some of the well known products/services around Authorization (RBAC and ABAC) that implement standards like XACML?
Our customers are organizations.
Each organization would be given 3 default roles (after onboarding)
but also have the capability to create more roles
Roles define level of access on the under lying resources (not just the API level (which is via scopes) but at the resource level)
Another use case is that of superuser who can act across organizations and perform any action.
Please share your thoughts on if these use cases can be solved (and the ease) in the product or service you recommend. thanks.
You can find a list of XACML implementations on the dedicated Wikipedia page. To address your use case which is very RBAC-oriented, I would use the RBAC Profile of XACML, so make sure the implementation you choose supports that.
cdan is right. Start with the Wikipedia page for XACML (and the ones for ABAC and ALFA) which list implementations but also use cases. You have quite a broad range of commercial and open-source alternatives.
In ABAC, you tend to try to write authorization policies independently of the underlying technology. This means that whether access is via APIs or via a webpage should not matter in defining the authorization.
The key questions you want to ask yourself are:
Are there relationships in authorizations? E.g.
a user with role='manager' can do action = 'view' on object = 'record' if object.organization == user.organization.
Do I care about auditing the authorization? Do I need to prove my compliance?
Do I need context and runtime attributes e.g. time and location?
Do I need to apply the same authorization logic across multiple apps, APIs, and data?
Do I need to regularly update my authorizations?
If you answered Yes to one or more of the above questions, you likely need ABAC.
My approach to develop a multi-tenant i.e. Shared Database, Separate Schemas ideally on PostgreSQL. One database for all tenants, but one schema per tenant similar to django tenant schemas. Is there a guide or addon to achieve this on websauna?
Here is what there is and there isn't
Already there
SQLAlchemy supports PostgreSQL tenancy. You can set this by overriding the database session factory when subclassing websauna.system.Initializer for your application. See configure_database that leads you to the path that allows to override create_dbsession. Your database session factory would look the properties of the HTTP request (domain) and configure session to point to the corresponding schema accordingly.
Add-on architecture that could provide a pluggable websauna.tenant addon
Theming: CSS and other assets (logo) can be customized by providing a site/base.html template that is a tenant aware. E.g. it injects css.html in <head> with the ability to define CSS filenames from the database. You would override the default site/base.html in the websauna.tenant addon.
Missing
Alembic migration supports PSQL schemas, but not sure how complete this support is
There isn't Tenant model e.g. to track the subscriber billing status
We are currently implementing a SCIM 2.0 based on the rfc7643; our current user database doesn't contains any group, either group management obviously.
We would like to know what is mandatory in order to be compliant with the industry .
Can we simply implement the user end-points or shall we implements the group/resources end-points as well.
Thanks for your help
The only way to know what is mandatory is to carefully read the relevant RFCs (RFC7643 and RFC7644).
In terms of your specific questions: firstly, whether implementation of groups is mandatory: RFC7643 section 4 says that:
This section defines the default resource schemas present in a SCIM
server. SCIM is not exclusive to these resources and may be extended
to support other resource types
In my reading, that implies that support for the Group schema as defined in that RFC in section 4.2, and the "/Groups" endpoint defined in RFC 7644 section 3.2, is mandatory. (Admittedly, the RFCs would be clearer on this point, if they actually used the word "MUST" in those sections.)
However, to my knowledge the SCIM standard nowhere requires that any groups actually exist, nor that any particular client have privilege to create them. So, if your server had a dummy implementation of groups, in which the Group schema exists, along with the /Groups endpoint, but no groups actually exist, and any attempt to create a group results in a HTTP Error 403 – that would comply. Another (somewhat more involved) option might be to have a single group "Everyone" of which everyone is automatically a member, but to reject any attempts to create further groups or remove any user from the "Everyone" group with a 403 error.
You also ask whether the filtering parameters are mandatory. RFC 7644 section 3.4.2.2 states that implementation of the filter= parameter is OPTIONAL. However, the startIndex= and itemsPerPage= parameters are not filtering parameters, rather they are pagination parameters. [Section 3.4.2.4]https://www.rfc-editor.org/rfc/rfc7644#section-3.4.2.2) defines pagination parameters, and unlike filtering (and sorting), it does not explicitly define it as OPTIONAL, which implies it is mandatory. Furthermore, the service provider config schema RFC 7643 section 5 defines attributes which the server can use to indicate which optional features it supports (e.g. patch, bulk, filter, sort, etc); there is no attribute to indicate whether the server implements pagination, which is further evidence that it is mandatory.
I am trying to figure out the "right" implementation for an url structure for an application with multitenancy support and shared resources.
Resources: Users, Projects
The URL schema is
host/api/tenant_id/resource[/id][/subresource][/id]
User A (width id = 1) gets a collection of his projects at
GET http://example.com/api/1/projects/
User A creates a new project, readable by
GET http://example.com/api/1/projects/2
Now User A gives another User B (id = 2) access to project 2.
User B would like to see a collection of all projects related to his account via:
GET http://example.com/api/2/projects/
Should the shared project (id = 2) be in this collection besides those, User B created by himself? Or is there a better naming structure for shared resources?
Focusing on the design of URL structures is actually a no-go for RESTful architectures. Roy Fielding:
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server).
See also this answer.
For your specific problem I would return a list of (basically arbitrary) hypertext links to the projects the user has access to. The links would contain attributes making it clear, whether the project is »owned« or »accessible« by the user. To improve readability you could design your resource URLs as
http://example.com/user/{user id}
http://example.com/project/{project id}
The representation of user after a GET http://example.com/user/2 would contain the list of links like
<a href="http://example.com/project/1" class="owned"/>
<a href="http://example.com/project/2" class="access-permitted"/>
The HATEOAS principle is inherent to REST and makes most »how do I design my URIs« questions obsolete:
The principle is that a client interacts with a network application entirely through hypermedia provided dynamically by application servers. A REST client needs no prior knowledge about how to interact with any particular application or server beyond a generic understanding of hypermedia.
Maybe one advantage can be in using tenant info in the path. In such way we can easily have for example the lists of objects.
Querying the uri on get /tenant-id/projects
We can have a list of of projects for each entry tenant.
How can be get without tenant info into url?
My 2 cents
I came across many different models for the Access Control in a system. When implementing an Access Control model in any system, we usually hard code the rules/rights in the database(considering an RDBMS) by creating separate tables for the Access Control. Also, these rules/rights can be stored in an XML database.
I would like to know what is the difference between storing the rules on RDBMS and on an XML database? Also, when should we use XACML for implementing an Access Control model in a system? I mean, how one can decide whether one should hardcode the rules/rights in the database or one should use XACML policy language?
Thanks.
Disclaimer: I work for Axiomatics, a vendor implementation of XACML
Storing authorization logic if you go your own way could be done either in the RDBMS or in an XML database. It doesn't matter. I doubt that XML brings you any added capabilities.
Now, if you want an authorization system that can cater for RDBMS systems and other types of applications too (CRM, .NET, Java...) then you want to use a solution that is agnostic of the type of application it protects. That's the goal of XACML, the eXtensible Access Control Markup Language.
XACML provides attribute-based, policy-based access control (ABAC and PBAC). This gives you the ability to write extremely expressive authorization policies and managed them centrally in a single repository. A central authorization engine (called Policy Decision Point or PDP) will then serve decisions to your different applications.
As Bell points out, the minimum set of attributes you will need is typically attributes about the user (Subject), the resource, and the action. XACML also lets you add environment attributes. This means you can write the following type of policy:
Doctors can view the medical records of patients they are assigned to.
Doctors describes the user / subject
view describes the action
medical records describes the targeted resource
of patients describes the targeted resource too. It's metadata about the resource
they are assigned to is an interesting case. It's an attribute that defines the relationship between the doctor and the patient. In ABAC, this gets implemented as doctor.id==patient.assignedDoctorId. This is one of the key benefits of using XACML.
Benefits of XACML include:
- the ability to externalize the authorization logic as mentioned by Bell
- the ability to update authorization logic without going through a development/deployment lifecycle
- the ability to have fine-grained authorization implemented the same way for many different applications
- the ability to have visibility and audits on the authorization logic
HTH
The two are not mutually exclusive.
An XACML policy describes how to translate a set of attributes about an attempted action into a permitted/denied decision. At minimum the attributes would be who the user is (Subject), what they are trying to do (Action) and what they are trying to do it to (Object). Information such as time, the source of the request and many others can be added.
The attributes of the user and the object will still have to be stored in the database. If you are grouping users or objects to simplify administration or to simplify defining access control rules then you're going to have to manage all of that in the database to. All that data will then need to be passed to the XACML Policy Decision Point to return the permit/deny decision.
The advantage of using XACML to define these rules, rather than writing your own decision logic for the rules defined in the database, is that the assessment of the rules can be handed off to an external application. Using a mature, tested XACML implementation (there are open source options) will avoid you making any mistakes in building the checks into your own code.
Hardcoding the policies in your code is a very bad practice I think. In that case you mix the business logic of your resources and the permission check of the access control system. XACML is a big step in the right direction because you can create a fully automatic access control system if you store your rules in a separated place (not hardcoded in the business logic).
Btw you can store that rules in the database too. For example (fictive programming language):
hardcoded RBAC:
#xml
role 1 editor
#/articles
ArticleController
#GET /
readAll () {
if (session.notLoggedIn())
throw 403;
if (session.hasRole("editor"))
return articleModel.readAll();
else
return articleModel.readAllByUserId(session.getUserId());
}
not hardcoded ABAC:
#db
role 1 editor
policy 1 read every article
constraints
endpoint GET /articles
permissions
resource
projections full, owner
role 2 regular user
policy 2 read own articles
constraints
endpoint GET /articles
logged in
permissions
resource
projections owner
#/articles
ArticleController
#GET /
readAll () {
if (session.hasProjection(full))
return articleModel.readAll();
else if (session.hasProjection(owner))
return articleModel.readAllByUserId(session.getUserId());
}
As you see the non hardcoded code is much more clear than the hardcoded because of the code separation.
The XACML is a standard (which knows 10 times more than the example above) so you don't have to learn a new access control system by every project, and you don't have to implement XACML in every language, because others have already done it if you are lucky...