wiki:NewStuff

Version 3 (modified by faber, 11 years ago) (diff)

--

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 GENI credentials
  • Support for human readable strings in credential printing

Self-contained Credentials

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 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 baked, 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:

<?xml version="1.0" encoding="UTF-8"?>
<signed-credential>
    <credential xml:id="ref0">
	<type>abac</type>
	<version>1.0</version>
	<expires>2013-06-17T23:15:44Z</expires>
	<rt0>ccae806d6e2ac13e39036d83ddc9d09a7f7bf23d.role&lt;-ccae806d6e2ac13e39036d83ddc9d09a7f7bf23d</rt0>
    </credential>
    <signatures>
     <!-- elided -->
    </signatures>
  </credential>
</signed-credential>

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:

<?xml version="1.0" encoding="UTF-8"?>
<signed-credential>
    <credential xml:id="ref0">
	<type>abac</type>
	<serial/>
	<owner_gid/>
	<target_gid/>
	<uuid/>
	<expires>2013-06-17T23:17:58Z</expires>
	<abac>
	    <rt0>
		<version>1.1</version>
		<head>
   <ABACprincipal><keyid>394d50f1f95468521ea1042c88047d8db1bebadd</keyid></ABACprincipal>
   <role>role</role>
</head>
<tail>
   <ABACprincipal><keyid>394d50f1f95468521ea1042c88047d8db1bebadd</keyid></ABACprincipal>
</tail>

	    </rt0>
	</abac>
    </credential>
    <signatures>
     <!-- elided -->
    </signatures>
  </credential>
</signed-credential>

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 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):

<?xml version="1.0" encoding="UTF-8"?>
<signed-credential>
    <credential xml:id="ref0">
	<type>abac</type>
	<serial/>
	<owner_gid/>
	<target_gid/>
	<uuid/>
	<expires>2033-06-13T00:44:54Z</expires>
	<abac>
	    <rt0>
		<version>1.1</version>
		<head>
   <ABACprincipal><keyid>cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd</keyid><mnemonic>Ted Faber</mnemonic></ABACprincipal>
   <role>ABAC_Guy</role>
</head>
<tail>
   <ABACprincipal><keyid>cf3cf09b762d89f0f6660e48b1b804e1fe7d53fd</keyid><mnemonic>Ted Faber</mnemonic></ABACprincipal>
</tail>

	    </rt0>
	</abac>
    </credential>
    <signatures>
    <!-- elided -->
    </signatures>
</signed-credential>