Tags: ,

Delegating certifiate issuance in FreeIPA

FreeIPA 4.2 brings several certificate management improvements including custom profiles and user certificates. Along with the explosion in certificate use cases that are now support comes the question of how to manage certificate issuance, along two dimensions: which entities can be issued what kinds of certificates, and who can actually request a certificate? The first aspect is managed via CA ACLs, which were explained in a previous article. In this post I detail how FreeIPA decides whether a requesting principal is allowed to request a certificate for the subject principal, and how to delegate the authority to issue certificates.

Self-service requests §

The simplest scenario is a principal using cert-request to request a certificate for itself as the certificate subject. This action is permitted for user and host principals but the request is still subject to CA ACLs; if no CA ACL permits issuance for the combination of subject principal and certificate profile, the request will fail.

Implementation-wise, self-service works because there are directory server ACIs that permit bound principals to modify their own userCertificate attribute; there is no explicit permission object.

Hosts §

Hosts may request certificates for any hosts and services that are managed by the requesting host. These relationships are managed via the ipa host-{add,remove}-managedby commands, and a single host or service may be managed by multiple hosts.

This rule is implemented using directory server ACIs that allow hosts to write the userCertificate attribute when the managedby relationship exists, otherwise not. In the IPA framework, we conduct a permission check to see if the bound (requesting) principal can write the subject principal’s attribute. This is nicer (and probably faster) than interpreting the managedby attribute in the FreeIPA framework.

If you are interested, the ACI rules look like this:

dn: cn=services,cn=accounts,$SUFFIX
aci: (targetattr="userCertificate || krbPrincipalKey")(version 3.0;
      acl "Hosts can manage service Certificates and kerberos keys";
      allow(write) userattr = "parent[0,1].managedby#USERDN";)

dn: cn=computers,cn=accounts,$SUFFIX
aci: (targetattr="userCertificate || krbPrincipalKey")(version 3.0;
      acl "Hosts can manage other host Certificates and kerberos keys";
      allow(write) userattr = "parent[0,1].managedby#USERDN";)

As usual, these requests are also subject to CA ACLs.

Finally, subjectAltName dNSName values are matched against hosts (if the subject principal is a host) or services (if it’s a service); they are treated as additional subject principals and the same permission and CA ACL checks are carried out for each.

Users §

FreeIPA’s Role Based Access Control (RBAC) system is used to assign certificate issuance permissions to users (or other principal types). There are several permissions related to certificate management:

Request Certificate

The main permission that allows a user to request certificates for other principals.

Request Certificate with SubjectAltName

This permission allows a user (one who already has Request Certificate permission) to request a certificate with the subjectAltName extension (the check is skipped when the request is self-service or initated by a host principal). Regardless of this permission we comprehensively validate the SAN extension whenever present in a CSR (and always have), so I’m not sure why this exists as a separate permission. I proposed to remove this permission and allow SAN by default but the conversation died.

Request Certificate ignoring CA ACLs (new in FreeIPA 4.2)

The main use case for this permission is where a certain profile is not appropriate for self-service. For example, if you want to issue certificates bearing some estoeric or custom extension unknown to (and therefore not validatable by) FreeIPA, you can define a profile that copies the extension data verbatim from the CSR. Such a profile ought not be made available for self-service via CA ACLs, but this permission will allow a privileged user to issue the certificates on behalf of others.

System: Manage User Certificates (new in FreeIPA 4.2.1)

Permits writing the userCertificate attribute of user entries.

System: Manage Host Certificates

Permits writing the userCertificate attribute of host entries.

System: Modify Services

Permits writing the userCertificate attribute of service entries.

There are other permissions related to revocation and retrieving certificate information from the Dogtag CA. It might make sense for certificate administrators to have some of these permissions but they are not needed for issuance and I will not detail them here.

The RBAC system is used to group permissions into privileges and privileges into roles. Users, user groups, hosts, host groups and services can then be assigned to a role. Let’s walk through an example: we want members of the user-cert-managers group to be able to issue certificates for users. The SAN extension will be allowed, but CA ACLs may not be bypassed.

It bears mention that there is a default privilege called Certificate Administrators that contains most of the certificate management permissions; for this example we will create a new privilege that contains only the required permissions. We will use the ipa CLI program to implement this scenario, but it can also be done using the web UI. Assuming we have a privileged Kerberos ticket, let’s first create a new privilege and add to it the required permissions:

ftweedal% ipa privilege-add "Issue User Certificate"
Added privilege "Issue User Certificate"
  Privilege name: Issue User Certificate

ftweedal% ipa privilege-add-permission "Issue User Certificate" \
    --permission "Request Certificate" \
    --permission "Request Certificate with SubjectAltName" \
    --permission "System: Manage User Certificates"
  Privilege name: Issue User Certificate
  Permissions: Request Certificate,
               Request Certificate with SubjectAltName,
               System: Manage User Certificates
Number of permissions added 3

Next we create a new role and add the privilege we just created:

ftweedal% ipa role-add "User Certificate Manager"
Added role "User Certificate Manager"
  Role name: User Certificate Manager

ftweedal% ipa role-add-privilege "User Certificate Manager" \
    --privilege "Issue User Certificate"
  Role name: User Certificate Manager
  Privileges: Issue User Certificate
Number of privileges added 1

Finally we add the user-cert-managers group (which we assume already exists) to the role:

ftweedal% ipa role-add-member "User Certificate Manager" \
    --groups user-cert-managers
  Role name: User Certificate Manager
  Member groups: user-cert-managers
  Privileges: Issue User Certificate
Number of members added 1

With that, users who are members of the user-cert-managers group will be able to request certificates for all users.

Conclusion §

In addition to self-service, FreeIPA offers a couple of ways to delegate certificate request permissions. For hosts, the managedby relationship grants permission to request certificates for services and other hosts. For users, RBAC can be used to grant permission to manage user, host and service principals, even separately as needs dictate. In all cases except where the RBAC Request Certificate ignoring CA ACLs permission applies, CA ACLs are enforced.

Looking ahead, I can see scope for augmenting or complementing CA ACLs - which currently are concerned with the subject or target principal and care nothing about the requesting principal - with a mechanism to control which principals may issue requests involving a particular profile. But how much this is wanted we will wait and see; it is one of many possible improvents to FreeIPA’s certificate management and all will have to be judged according to the demand and impact.

Creative Commons License
Except where otherwise noted, this work is licensed under a Creative Commons Attribution 4.0 International License .