Fixed phone call meetings
by Anil Saldhana
Hi All,
we will have fixed phone call meetings on Mondays (every 2 weeks)
starting Nov 19th as follows:
Chicago :9am
Sao Paulo: 1pm
Prague: 4pm
Please put it on your calendars.
Phone Numbers can be obtained by asking in #picketbox or #picketlink on
freenode.
We will have hangouts on Thursdays every 2 weeks, starting Nov 22nd
*Unfortunately, next week both the phone and hangout is canceled due to
US thanksgiving (Thu) and I am on PTO (Mon).*
But please watch out for invitations coming into your inbox. :)
Regards,
Anil
12 years
IDM project on critical path
by Anil Saldhana
Hi All,
the IDM project is now on critical path. We need to stabilize the API
and get the unit tests in place. Projects cannot move forward without
IDM. :)
Regards,
Anil
12 years
IDM Realms, take 3
by Shane Bryzak
Ok guys, brace yourselves:
Realm/Tier relationships
In this design I've tried to address both David's and Bill's use cases,
by introducing a hierarchical Tier structure and adding support for
Tier-specific groups. Specific constraints I'll describe in the
following sections:
Users
--------
1. A User is specific to a realm
2. A User may be assigned a group role where both the group and role
exist either in the realm (i.e. a global group role), or in a tier
(tier-specific group role)
3. A User may be a member of a group, where the group exists either in
the realm (i.e. a global group) or in a tier (tier-specific group
membership)
4. A User may be granted a global role (where the role exists in the
same realm of the user), or a tier-specific role (where the role exists
in a tier)
Groups
----------
5. A Group may belong to a realm (i.e. a global Group), or to a tier (a
tier-specific Group)
6. A Group may be a subgroup of another Group within the same realm or
the same tier
7. A global Group may be a member of a tier-specific Group, in which
case all members of the global Group are also treated as members of the
tier-specific Group
8. A global Group may be granted a global role (where the role exists in
the same realm of the Group)
9. A global Group may be granted a tier-specific Role
10. A tier-specific Group may be granted a tier-specific Role when the
Role exists in the same tier of the Group
11. Members of a Group automatically inherit all privileges assigned to
the Group, and the Group's parent Group
Roles
-------
12. A Role may belong to a realm (i.e. a global Role) or to a tier (a
tier-specific Role)
13. Privileges granted to a User or Group with a tier-specific Role are
inherited by the sub-tiers of the Role's tier
I *think* that pretty much describes all constraints of this design. If
anyone is interested (or is confused by this), I can follow up on this
with a bunch of examples to illustrate the constraints in an
easier-to-digest format. I'm quite certain that this design should
address all the use cases described so far, but as always I'd like to
hear feedback (especially from Bill and David). Unfortunately this
means that the stabilization of the IDM API has to be delayed a little
longer however I believe that it is worth it in the interest of nailing
down the best design possible before we proceed to code the implementation.
12 years
Fwd: [javaee-spec users] [jsr342-experts] security permissions for libraries
by Jason Porter
Not sure who's seen this yet.
Begin forwarded message:
> From: Bill Shannon <bill.shannon(a)oracle.com>
> Date: November 16, 2012, 17:18:12 MST
> To: jsr342-experts(a)javaee-spec.java.net
> Subject: [javaee-spec users] [jsr342-experts] security permissions for libraries
> Reply-To: jsr342-experts(a)javaee-spec.java.net
>
> As described in this document:
> http://java.net/projects/javaee-spec/downloads/download/ee-sec-mgr-00-ljm...
> we plan to add the ability to include a permissions.xml file with an
> application to control what security permissions the application gets.
>
> Our intent was to support this only at the module level, e.g., only for a
> war file, ejb-jar file, or app client jar file. This raises a question
> I'd like your opinion on...
>
> What permissions should apply to libraries in the "lib" directory of an
> ear file?
>
> Ultimately we'd like to allow each such library to include a permissions.xml
> file of its own, but even then we need to decide what permissions should
> apply if the library doesn't include a permissions.xml file.
>
> Remember that libraries are available to all modules of the application.
>
> There seem to be a few options:
>
> 1. The permissions for the library are the same as the permissions for
> the code that calls the library. If the library code is called from
> a war file, it gets the permissions of the war file. If the same
> library is called from an ejb-jar file, it gets the permissions of
> the ejb-jar file.
>
> 2. The permissions for the library are the default permissions for the
> container calling the library. As above, the permissions would vary
> based on what code calls the library, but would always be the default
> permissions for that container, even though the calling code might
> have more or fewer permissions than the default. (It's not clear to
> me that this is implementable.)
>
> 3. We allow a permissions.xml file to be included in the "lib" directory.
> All the libraries in the "lib" directory get these permissions, no
> matter which container is calling them.
>
> Note that in addition to libraries in the "lib" directory of an ear file,
> modules can use a Class-Path entry to reference other libraries anywhere
> in the ear file. I think #1 above is the only viable choice for this
> case.
>
> Again, in a future release we hope to support a permissions.xml file in
> the library jar file itself.
>
> How do you think we should handle security permissions for libraries in
> this release?
12 years
IDM Realms and Applications - The Nitty Gritty
by Shane Bryzak
I'd like to go through the proposed design for Realms and Applications
in detail, as this is quite an important feature to get right and we all
need to be on the same page with this before we proceed.
To start with the basics, let's look at the relationship between Realms
and Applications:
Realms and Applications
Each realm is a totally segregated "island" of identity state, with no
crossover of state between the realms. Applications, Users, Groups and
Roles only exist within the scope of their containing realm. Realms are
top level constructs, and due to reasons of complexity and practicality
we don't support a Realm "hierarchy"; i.e. there are no Realms within
Realms.
Let's take a look next at how Users and Groups fit into this:
Users and Groups
All User and Group objects are first class citizens within a Realm. If
we think of this in terms of the corporate model, a company may be
represented by a single Realm, with its employees as Users. Each
department and sub-division could be represented as a Group, with Users
(employees) belonging to one or more of these Groups. There is also a
hierarchy for Groups, which allows greater flexibility in defining the
company structure. Let's take a closer look at how this structure is
defined:
User and Group Memberships
Each User can be a member of zero or more Groups, while each Group may
be a subgroup of one parent Group.
Let's take a look at Roles next. While both Users and Groups sit at the
top level of the Realm, Roles are all application specific:
Roles
Each Application may define zero or more Roles, each of which may be
used within the scope of the Application's authorization rules to
determine the appropriate privilege levels for Users. Roles may be
granted to either a User or a Group, as illustrated by the following
diagram:
User and Group Roles
Each role may be granted as an Application Role (i.e. a Role membership
that has no Group component) or as a "standard" Role (which does have a
Group component). An Application Role is used to grant broad
application privileges to a select User or Group, for example you might
wish to grant an Application-specific "admin" role to all members of the
"/employees/itdepartment/managers" Group. A standard role is used when
you wish to grant a Group-specific privilege to either an individual
User or a Group of Users, for example granting a User the Role
"TechSupport" for the Group "/department/cardiology/doctors".
So in summary, PicketLink will support:
1) Realms, which represent top level boundaries of segregated identity
state, and are arranged in a flat (rather than hierarchical) structure.
2) Applications, which essentially represent a group of services and
resources.
3) Roles, which are specific to an Application and are defined for the
purpose of controlling access to the services and resources provided by
the Application.
4) Users, a top level construct within a Realm that represents an entity
that may access the services and resources provided by one or more
Applications.
5) Groups, another type of top level construct within a Realm, arranged
within a hierarchical structure and that may be used to define broader
associations of Users and sub-Groups for the purpose of assigning
coarse-grained privileges to an Application's services and resources.
Impact on Identity Management API
-----------------------------------------------
One of the most important factors in implementing support for Realms and
Applications is the impact on the IDM API. As a primary goal for
PicketLink is to provide a simplified API for developers, this support
must be provided in a manner that doesn't pollute the API with
unnecessary complexity. To that end, let's start by looking at the
simplest use case, in which a developer embeds PicketLink into their own
application.
Default Realm and Application
--------------------------------------
To allow for a developer to use PicketLink in the simplest way possible,
I propose that we introduce the concept of a "default" Realm and
"default" Application. By doing this, we can allow the developer to
simply use the basic PicketLink API without having to be aware of these
more advanced features. For example, let's pretend that the developer
wants to create a new User:
User user = new SimpleUser("jsmith");
If we were forcing the developer to deal with Realms and Applications,
they would then have to write something like this to create the new User:
identityManager
.forRealm("default")
.createUser(user);
However by assuming that an unspecified Realm is the "default" realm,
the code looks like this:
identityManager
.createUser(user);
If the default Realm doesn't exist at the time, it will be created
automatically (the same goes for the default Application).
Likewise, when creating a new Role:
Role role = new SimpleRole("admin");
The developer would have to write the following code if we didn't
support a default application:
identityManager
.forApplication("default")
.createRole(role);
If we do support a default though, the code looks like this:
identityManager
.createRole(role);
As a side note, the above examples are slightly contrived because the
forRealm() and forApplication() methods wouldn't accept a String (rather
they'd expect either a Realm or Application object) - this leads us into
our next point.
Realm and Application Management
----------------------------------------------
To properly support Realms and Applications we will require a number of
management methods, similar to what we have for Users, Groups and
Roles. I propose the addition of the following methods to IdentityManager:
void createRealm(Realm realm);
Realm getRealm(String realm);
void removeRealm(Realm realm);
Collection<Realm> getRealms();
void createApplication(Application application);
Application getApplication(Realm realm, String application);
void removeApplication(Application application);
Collection<Application> getApplications(Realm realm);
This obviously requires the addition of two new classes to the model API
also, Realm and Application:
public class Realm {
private String name;
public Realm(String name) {
this.name = name;
};
public String getName() {
return name;
}
}
public class Application {
private Realm realm;
private String name;
public Application(Realm realm, String name) {
this.realm = realm;
this.name = name;
}
public Realm getRealm() {
return realm;
}
public String getName() {
return name;
}
}
Usage
--------
One other thing I'd like to discuss is usage scenarios, specifically in
Java EE6 applications. I'd like to propose that we provide a producer
method that supports the following form of injection for the
IdentityManager:
First of all, injecting an IdentityManager that uses the default Realm
and default Application (the most common use case for embedded PicketLink):
@Inject IdentityManager identityManager;
Secondly, injecting an IdentityManager for a specific Realm:
@Inject @ForRealm("public") IdentityManager identityManager;
Lastly, injecting an IdentityManager for a specific Application:
@Inject @ForRealm("public") @ForApplication("forums") IdentityManager
identityManager;
It would also be nice if we could provide support for "configure once",
where the developer can configure a specific Realm and Application and
any injected IdentityManager would default to using them. There's
probably a few different ways to achieve this, so if anyone has a
preference please let me know.
Summary
------------
This pretty much describes the entire proposal for Realms and
Applications. I'd like all stakeholders to please carefully review the
design, in particular the 5 summary points that describe the
restrictions of this model. If we all agree on this, then we should be
able to release a stable version of the API very shortly. Some further
work may be required the bring the configuration and some IdentityStore
implementation details inline with the new design, but that won't affect
the API.
Thanks!
Shane
12 years
[PicketLink IDM] - Test Cases
by Pedro Igor Silva
Hi All,
I'm starting to write some test cases for PicketLink IDM to assert what we have so far. The idea is provide a good suite that covers all the functionality we already have, built-in identity stores (jpa and ldap, mainly) and specific usage scenarios. I think this is an important step to stabilizes the API.
During this work I'll be documenting all test cases and issues that were found (or we can start using the JIRA ?). As you can see here:
https://gist.github.com/4088060
More tests will be added to the list for each functionality. As a start point, for now I'll be working with the user basic management operations.
Shane, I've found some issues during my first test case. Wondering if you already have something to solve them or if I can fix/implement the missing parts.
Regards.
Pedro Igor
12 years
Security Development Hangout
by Anil Saldhana
Hi All,
I am wondering if we can have a hangout this Thu or Fri (or next week).
Preferences for time?
Regards,
Anil
12 years
Meetings via phone call biweekly
by Anil Saldhana
Hi All,
apart from the biweekly Google hangouts, I am going to set up a time
every two weeks Monday morning (US Time) for the security developers to
talk over the phone.
This will give everyone an opportunity to participate in the development.
Regards,
Anil
12 years
IdentityManager API review
by Shane Bryzak
Hey guys,
I spent some time reviewing the IdentityManager API today to identify
any redundancies and also locate any holes where we might not properly
support required features, as well as a general "sanity" check to ensure
that what we're exposing via this API makes sense and is intuitive for
consumers. As Anil has pointed out already, our short term priority for
the project is to stabilize the API - this is extremely important as
PicketLink will provide the security foundation for many other
projects. With that in mind I'd like to strongly encourage everyone
with a stake in this to carefully review the API and provide feedback,
as once we release it it will be essentially set in stone.
To try and avoid a wall of text (and make this post easier to reply to),
I'm going to break this post up into sub-sections, one for each feature
group. For each section, I'll include the API as it currently exists,
followed by a brief summary of my thoughts and any recommendations I may
have - this is especially where I want to hear any feedback indicating
whether you agree or disagree with my assessment. Let's start with the
user-related methods:
User management
-------------------------
User createUser(String name);
void createUser(User user);
void removeUser(User user);
void removeUser(String name);
User getUser(String name);
My thoughts:
1. I'm wondering if we should remove the createUser(String) method and
just have createUser(User). This would make sense in a way because I
can't think of many use cases where you might want to create a User with
just a username and not any of the other typical information (such as
first name, last name, e-mail address, etc). Creating a User via
createUser(String) when you actually want to set the other details after
the initial User creation is also horribly inefficient, requiring
multiple round trips to the database (or whatever identity store backend
you use). To add to that, the actual parameter name is a little
unintuitive - "name" could refer to any number of things - is it the
username or the user's actual name that you need to provide here? My +1
goes to removing createUser(String).
2. Similar to point 1), having two removeUser() methods seems equally
redundant. The User object that needs to be provided to the
removeUser(User) method can be easily looked up by calling getUser(), as
per this example:
identityManager.removeUser(identityManager.getUser("jsmith"));
3. As I also pointed out in point 1), the "name" parameter is a little
unintuitive. In regard to the getUser() method I think we should rename
the "name" parameter to "username" just so it's perfectly clear what the
method expects.
4. We don't currently have any way to update User details. I recommend
that we add an updateUser() method as follows:
void updateUser(User user);
This will allow User details such as their first and last name, e-mail
address etc to be updated without having to delete and re-create the
User. Extending on this a little further, I'm wondering if we should
think about adding an audit API that logs these changes. Perhaps it's
something to think about for a later release.
Group management
--------------------------
Group createGroup(String id);
Group createGroup(String id, Group parent);
Group createGroup(String id, String parent);
void removeGroup(Group group);
void removeGroup(String groupId);
Group getGroup(String groupId);
Group getGroup(String groupId, Group parent);
void addToGroup(IdentityType identityType, Group group);
void removeFromGroup(IdentityType identityType, Group group);
My thoughts:
1. I think there is a little bit of ambiguity here in regard to the
differences between a Group's ID and name. To assist in understanding
the differences, here's the JavaDoc pasted from the Group interface:
/**
* Groups are stored in tree hierarchy and therefore ID represents
a path. ID string always begins with "/" element that
* represents root of the tree
* <p/>
* Example: Valid IDs are "/acme/departments/marketing",
"/security/administrator" or "/administrator". Where "acme",
* "departments", "marketing", "security" and "administrator" are
group names.
*
* @return Group Id in String representation.
*/
String getId();
/**
* Group name is unique identifier in specific group tree branch.
For example group with id "/acme/departments/marketing"
* will have name "marketing" and parent group of id
"/acme/departments"
*
* @return name
*/
String getName();
Taking the above JavaDoc into account, it seems that where we are
specifying "id" as a method parameter we should be specifying "name"
instead. If we are indeed providing a "fully qualified" path to the
createGroup() method, then there is no need to also specify the parent
as it can be easily derived from the path. More on this in the
following points.
2. We currently have three createGroup() methods for creating a new
Group. I think we should remove the (String, String) variant, as the
parent parameter is ambiguous (is it the parent's ID or name we need to
specify here?), and rename the "id" parameter of the (String, Group)
variant to "name", leaving us with the following:
Group createGroup(String id);
Group createGroup(String name, Group parent);
This then gives us two ways of creating a group. We can either specify
the fully qualified group ID:
Group employees = identityManager.createGroup("/employees");
Or we can specify a subgroup name and parent Group:
Group managers = identityManager.createGroup("managers", employees);
We can also use this second form to create a "root" group by just
specifying null for the parent:
Group admins = identityManager.createGroup("admins", null);
3. For the removeGroup() methods, I think what we have is fine.
4. For the getGroup() methods, I'm happy with the first one (String
groupId) but I think the second one (String groupId, Group parent) needs
to be (String name, Group parent) instead. The first method would be
used when the fully qualified group ID is known, and the second one
would be used when you already have the parent Group and know the name
of the subgroup.
5. The addToGroup() and removeFromGroup() methods seem fine to me.
6. One thing we don't have is a method to test whether an IdentityType
is a member of a Group. I suggest we add another method to support this:
boolean inGroup(IdentityType identityType, Group group);
Roles
----------
Role createRole(String name);
void removeRole(Role role);
void removeRole(String name);
Role getRole(String name);
boolean hasRole(Role role, IdentityType identityType, Group group);
void grantRole(Role role, IdentityType identityType, Group group);
void revokeRole(Role role, IdentityType identityType, Group group);
My thoughts:
1. I would remove the removeRole(String) method as the same thing can be
achieved with removeRole(getRole(String)).
2. I would swap the order of the Role and IdentityType parameters within
the hasRole(), grantRole() and revokeRole() methods. As the
IdentityType is the primary artifact in these operations it makes sense
to have it listed first.
3. We don't have any explicit support for application roles, which are
roles where there is no Group component (for example, an
application-wide "admin" role). We could support this by just allowing
hasRole(), grantRole() etc to accept null values for the Group
parameter, however I feel it would be more semantically correct to
provide a distinct set of methods for the purpose of supporting
application roles, as follows:
boolean hasApplicationRole(IdentityType identityType, Role role);
void grantApplicationRole(IdentityType identityType, Role role);
void revokeApplicationRole(IdentityType identityType, Role role);
Query API
--------------
<T extends IdentityType> IdentityQuery<T> createQuery();
My thoughts:
1. After our recent rewrite of the Query API I'm satisfied with what we
have now.
Credential management
-------------------------------
boolean validateCredential(User user, Credential credential);
void updateCredential(User user, Credential credential);
My thoughts:
1. I'm satisfied with what we currently have, however we still need to
review the mechanism that we provide for encoding passwords. I'm not
sure that it will have any effect on these methods though (I'm toying
with the idea of integrating the password encoding functionality via the
IdentityStoreInvocationContext).
Identity expiry
------------------
void setEnabled(IdentityType identityType, boolean enabled);
void setExpirationDate(IdentityType identityType, Date expirationDate);
My thoughts:
1. I think these methods are fine the way they are. One discrepancy
that I've identified is that a User can be created already being
disabled or having an expiry date, while for a Role or Group the
equivalent status must be set via these methods after creation. I'm not
sure this is a big deal though.
Attributes
-------------
void setAttribute(IdentityType identityType, String attributeName,
String attributeValue);
String getAttribute(IdentityType identityType, String attributeName);
My thoughts:
1. This area poses a slight dilemma. Currently the API only supports
simple String-based attribute values, however I'm pretty sure that
people are going to want to store all sorts of things, ranging from
boolean and Date values through to large byte arrays that store a User's
photograph or other data. If everyone is in agreement that we need to
support more than just String values, then the first thing we probably
need to do is modify these methods to work with a Serializable instead.
2. If we all agree on point 1), the next thing we need to decide is
whether we want the capability to make some attribute values "lazy
loaded". If we want to do a quick lookup of a User object for the
express purpose of assigning a Role or Group membership (or any other
type of simple operation) then we probably don't want the performance
hit of having to load bulky attribute data.
3. With the above two points in mind, I'm going to hold off on surmising
any further on attributes until some of you guys weigh in with your
opinions. I do have some rough ideas, however I'll wait until we have a
consensus of exactly what we want to achieve here before we proceed further.
Utility methods
--------------------
IdentityType lookupIdentityByKey(String key);
My thoughts:
1. This method is required by other features, such as the Permissions
API. I'm fine with what we have here.
In summary
----------------
I apologise for yet another epic e-mail to the list, however this is
everyone's chance to review the API for themselves and decide whether or
not it will be suitable for addressing all of your requirements. I'd
like to get this API stable by next week so please don't be shy about
speaking up. I'm especially looking forward to hearing your opinions
about how we handle attributes (there may even be some relevant JSR-351
stuff that we should be looking at here).
Thanks,
Shane
12 years