[[TOC]]
= New Features In The Coming Release =
This page describes features being developed for libabac and currently available on the {{{tvf-new-xml}}} branch of the git repository. There are three new features:
* Simplified input of self-contained credentials
* Support for multiple credential formats
* Support for Version 1.1 [http://groups.geni.net/geni/wiki/TIEDCredentials GENI credentials]
* Support for human readable strings in credential printing
== Self-contained Credentials ==
[http://groups.geni.net/geni/wiki/TIEDCredentials GENI credentials] are self-contained in that they include the issuer's identity certificate. Earlier versions of libabac required applications to load an identity via {{{load_id_chunk}}} or {{{load_id_file}}}. This version relazes this restriction. A GENI credential can be read without calling any of the ID loading routines.
Both of these load a GENI credential from {{{./GENIcred.xml}}} that was issued by the identity in {{{./issuer.pem}}}.
Old code:
{{{
import ABAC
ctx = ABAC.Context()
ctx.load_id_file('./issuer.pem')
ctx.load_attribute_file('./GENIcred.xml')
}}}
New code:
{{{
import ABAC
ctx = ABAC.Context()
ctx.load_attribute_file('./GENIcred.xml')
}}}
== New Credential Formats and Multiple Credential Formats ==
This release supports multiple credential formats, specifically version 1.0 and version 1.1 [http://groups.geni.net/geni/wiki/TIEDCredentials GENI credentials] as well as reading GENI privilege credentials. Credentials read from files or chunks are transparently output as read, for example if they appear in a proof or if they are extracted from a context. Credentials that are created by an application are output in GENI v1.1 format by default, but can be created in GENI v1.0 format using the {{{set_output_format}}} method of the Attribute object. Valid parameters to {{{set_output_format}}} are:
* GENIv1.0
* GENIv1.1
Note that the output format must be set before the attribute is {{{bake}}}d, and that the format cannot be changed after {{{bake}}} has been called.
This code:
{{{
#!/usr/local/bin/python
import sys
import ABAC
i = ABAC.ID("TestPrincipal", 10 * 356 * 24 * 3600)
a = ABAC.Attribute(i, "role", 3600)
# Here's the format change
a.set_output_format("GENIv1.0")
# Format change above
a.principal(i.keyid());
a.bake()
a.write(sys.stdout)
}}}
Produces output similar to:
{{{
abac
1.0
2013-06-17T23:15:44Z
ccae806d6e2ac13e39036d83ddc9d09a7f7bf23d.role<-ccae806d6e2ac13e39036d83ddc9d09a7f7bf23d
}}}
This code:
{{{
#!/usr/local/bin/python
import sys
import ABAC
i = ABAC.ID("TestPrincipal", 10 * 356 * 24 * 3600)
a = ABAC.Attribute(i, "role", 3600)
# Here's the format change
a.set_output_format("GENIv1.1")
# Format change above
a.principal(i.keyid());
a.bake()
a.write(sys.stdout)
}}}
Produces:
{{{
abac
2013-06-17T23:17:58Z
1.1
394d50f1f95468521ea1042c88047d8db1bebadd
role
394d50f1f95468521ea1042c88047d8db1bebadd
}}}
Should you need to know the format in which an Attribute will be output:
{{{
#!/usr/local/bin/python
import ABAC
i = ABAC.ID("TestPrincipal", 10 * 356 * 24 * 3600)
a = ABAC.Attribute(i, "role", 3600)
print a.get_output_format()
}}}
== Printing Credentials Using Mnemonic Names Instead of Keyids ==
Internally libabac uses the SHA1 hash of a principal's public key to identify them, but when printing credentials and debugging policy it can be confusing to keep track of the hashes. The latest release keeps track of mnemonic names for principals within the scope of a Context. The names can be specified in the common name of an X.509 identity certificate, the {{{mnemonic}}} element of a [http://groups.geni.net/geni/wiki/TIEDCredentials version 1.1 GENI abac credential], or specified on a per-Context basis using the Context's {{{set_nickname}}} method.
When printing a role from a credential, the {{{short_string(}}}''context''{{{)}}} method will scan the role for keyids that have mnemonics in that context and return a translated string. For exmaple:
{{{
import ABAC
ctx = ABAC.Context()
ctx.load_attribute_file('./GENIcred.xml')
for c in ctx.credentials():
print "Raw: %s -> %s" % (c.head().string(), c.tail().string())
print "Short: %s -> %s" % (c.head().short_string(ctx), c.tail().short_string(ctx))
}}}
Produces output similar to:
{{{
Raw: cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd.experiment_create -> cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd.partner.experiment_create
Short: Acme.experiment_create -> Acme.partner.experiment_create
}}}
The nicknames are initialized by the common name in the X.509 certificate, and will be overwritten by the most {{{mnemonic}}} field of the most recent credential imported. The following resets the nicknames of all the identities:
{{{
import ABAC
ctx = ABAC.Context()
ctx.load_attribute_file('./GENIcred.xml')
for c in ctx.credentials():
print "Raw: %s -> %s" % (c.head().string(), c.tail().string())
print "Short: %s -> %s" % (c.head().short_string(ctx), c.tail().short_string(ctx))
# Collect the identity keyids into ids
ids = []
for c in ctx.credentials():
i = ABAC.ID_chunk(c.issuer_cert())
if i.keyid() not in ids:
ids.append(i.keyid())
# Change all the nicknames
for n, i in enumerate(ids):
ctx.set_nickname(i, "identity%d" % n)
# Print the credentials with the new nicknames
print ""
print "After modifications"
print ""
for c in ctx.credentials():
print "Raw: %s -> %s" % (c.head().string(), c.tail().string())
print "Short: %s -> %s" % (c.head().short_string(ctx), c.tail().short_string(ctx))
}}}
It produces output like:
{{{
Raw: cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd.experiment_create -> cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd.partner.experiment_create
Short: Acme.experiment_create -> Acme.partner.experiment_create
After modifications
Raw: cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd.experiment_create -> cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd.partner.experiment_create
Short: identity0.experiment_create -> identity0.partner.experiment_create
}}}
The names in a context can be exported new credentials by calling bake with the context containing the nickname:
{{{
import sys
import ABAC
ctx = ABAC.Context()
ctx.load_id_file('./issuer.pem')
i = ABAC.ID('./issuer.pem')
ctx.set_nickname(i.keyid(), 'Ted Faber')
a = ABAC.Attribute(i, 'ABAC_Guy', 20 * 365 * 24 * 3600)
a.principal(i.keyid())
a.bake(ctx)
a.write(sys.stdout)
}}}
Produces (note the {{{mnemonic}}} elements):
{{{
abac
2033-06-13T00:44:54Z
1.1
cf3cf09b762d89f0f6660e48b1b804e1fe7d53fdTed Faber
ABAC_Guy
cf3cf09b762d89f0f6660e48b1b804e1fe7d53fdTed Faber
}}}