[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://http://groups.geni.net/geni/wiki/TIEDCredentials GENI credentials] * Support for human readable strings in credential printing == Self-contained Credentials == [http://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') }}} Identities loaded incidentally are includes in the results of the Context's {{{identities}}} method. == New Credential Formats and Multiple Credential Formats == This release supports multiple credential formats, specifically version 1 and version 1.1 [http://http://groups.geni.net/geni/wiki/TIEDCredentials GENI credentials] as well as reading GENI privilege credentials. Credentials read from files or chunks are transparenlty 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 using the set_output format 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://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 }}}