diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index c07cdf70918ddaa4dbc972f27fae5c7838d3ee8a..6b452b303a949b5b64fc1a3b6142e5bd0d6908e1 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -52,6 +52,7 @@ libcommon_la_SOURCES = 			\
 	slurm_protocol_defs.h		\
 	util-net.c util-net.h		\
 	slurm_auth.c slurm_auth.h	\
+	arg_desc.c arg_desc.h		\
 	macros.h			\
 	$(elan_sources) 
 
diff --git a/src/common/arg_desc.c b/src/common/arg_desc.c
new file mode 100644
index 0000000000000000000000000000000000000000..566ae5282542d0f2542a8ff56a4e478dd766e027
--- /dev/null
+++ b/src/common/arg_desc.c
@@ -0,0 +1,50 @@
+#include <string.h>
+#include "src/common/arg_desc.h"
+#include "src/common/xassert.h"
+
+const int
+arg_count( const arg_desc_t *desc )
+{
+	int i;
+
+	if ( desc == NULL ) return 0;
+
+	i = 0;
+	while ( desc[ i ].name != NULL ) ++i;
+
+	return i;
+}
+
+
+const int
+arg_idx_by_name( const arg_desc_t *desc, const char *name )
+{
+	int i;
+
+	if ( desc == NULL ) return -1;
+	if ( name == NULL ) return -1;
+	
+	for ( i = 0; desc[ i ].name != NULL; ++i ) {
+		if ( strcmp( desc[ i ].name, name ) == 0 ) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+
+const char *
+arg_name_by_idx( const arg_desc_t *desc, const int idx )
+{
+	int i = idx;
+
+	if ( desc == NULL ) return NULL;
+
+	while ( i > 0 ) {
+		if ( desc[ i ].name != NULL ) --i;
+	}
+
+	return desc[ i ].name;
+}
+
diff --git a/src/common/arg_desc.h b/src/common/arg_desc.h
new file mode 100644
index 0000000000000000000000000000000000000000..1de433503a8db131fd0335005e4728a482d9dde5
--- /dev/null
+++ b/src/common/arg_desc.h
@@ -0,0 +1,71 @@
+#ifndef __ARG_DESC_H__
+#define __ARG_DESC_H__
+
+/*
+ * An argument descriptor is a named positional parameter in an
+ * argv-like vector of arguments.  An array of named parameters
+ * constitutes the descriptor, and the index (zero-based) in the
+ * array of the named parameter is also its index in the argument
+ * vector.
+ *
+ * The descriptor array must be terminated by an entry whose name
+ * is the NULL pointer.
+ *
+ *	arg_desc_t arg_desc[] = {
+ *		{ "foo" },
+ *		{ "bar" },
+ *		{ NULL }
+ *	};
+ *
+ * For vectors which are finalized at initialization, the receiving
+ * functions can call arg_idx_by_name() and cache the value in
+ * order to accelerate argument processing.
+ *
+ * For well-defined APIs containing explicit initialization routines,
+ * this can be done at initialization, as in
+ *
+ *	void init( arg_desc_t *desc )
+ *	{
+ *		static_foo_idx = arg_idx_by_name( desc, "foo" );
+ *	}
+ *
+ *	void need_foo( void *argv[] )
+ *	{
+ *		foo_type foo = (foo_type) argv[ static_foo_idx ];
+ *		...
+ *	}
+ *
+ * For vectors which may vary for each invocation of the function,
+ * it is best to pass the argument descriptor array as a first-class
+ * parameter to the function:
+ *
+ *	void need_foo_dynamic( arg_desc_t *desc, void *argv[] )
+ *	{
+ *		int idx = arg_idx_by_name( desc, "foo" );
+ *		foo_type foo = (foo_type) argv[ idx ];
+ *	}
+ */
+
+typedef struct _arg_desc {
+    char *name;
+} arg_desc_t;
+
+/*
+ * Return the number of argument names in the descriptor.
+ */
+const int arg_count( const arg_desc_t *desc );
+
+/*
+ * Return the index in the descriptor corresponding to the name.
+ *
+ * Returns -1 if the name can't be found.
+ */
+const int arg_idx_by_name( const arg_desc_t *desc, const char *name );
+
+/*
+ * Return the name of the argument for the given index, or NULL if
+ * the index is invalid.
+ */
+const char *arg_name_by_idx( const arg_desc_t *desc, const int idx );
+
+#endif /*__ARG_DESC_H__*/
diff --git a/src/common/slurm_auth.c b/src/common/slurm_auth.c
index d9d8222cf8e286d80e2c5e546f2d7f34e9ae1277..90ccebeaba5434718b8ab6c700f21b4acd11e295 100644
--- a/src/common/slurm_auth.c
+++ b/src/common/slurm_auth.c
@@ -37,6 +37,7 @@
 #include "src/common/slurm_auth.h"
 #include "src/common/plugin.h"
 #include "src/common/plugrack.h"
+#include "src/common/arg_desc.h"
 
 /*
  * WARNING:  Do not change the order of these fields or add additional
@@ -45,9 +46,9 @@
  * end of the structure.
  */
 typedef struct slurm_auth_ops {
-	void *	(*create)	( void );
+	void *	(*create)	( void *argv[] );
 	int	(*destroy)		( void *cred );
-	int	(*verify)	( void *cred );
+	int	(*verify)	( void *cred, void *argv[] );
 	uid_t	(*get_uid)	( void *cred );
 	gid_t	(*get_gid)	( void *cred );
 	int	(*pack)		( void *cred, Buf buf );
@@ -94,6 +95,15 @@ static pthread_mutex_t      context_lock = PTHREAD_MUTEX_INITIALIZER;
 static slurm_ctl_conf_t conf;
 static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
 
+/*
+ * Order of advisory arguments passed to some of the plugins.
+ */
+static arg_desc_t auth_args[] = {
+	{ ARG_HOST_LIST },
+	{ ARG_TIMEOUT },
+	{ NULL }
+};
+
 
 static char *
 get_plugin_dir( void )
@@ -182,6 +192,44 @@ slurm_auth_get_ops( slurm_auth_context_t c )
 	return &c->ops;
 }
 
+const arg_desc_t *
+slurm_auth_get_arg_desc( void )
+{
+	return auth_args;
+}
+
+void **
+slurm_auth_marshal_args( void *hosts, int timeout )
+{
+	static int hostlist_idx = -1;
+	static int timeout_idx = -1;
+	static int count = sizeof( auth_args ) / sizeof( struct _arg_desc ) - 1;
+	void **argv;
+	
+	/* Get indices from descriptor, if we haven't already. */
+	if ( ( hostlist_idx == -1 ) &&
+		 ( timeout_idx == -1 ) ) {
+		hostlist_idx = arg_idx_by_name( auth_args, ARG_HOST_LIST );
+		timeout_idx = arg_idx_by_name( auth_args, ARG_TIMEOUT );		
+	}
+
+	argv = xmalloc( count * sizeof( void * ) );
+	
+	/* Marshal host list.  Don't quite know how to do this yet. */
+	argv[ hostlist_idx ] = hosts;
+
+	/* Marshal timeout. */
+	argv[ timeout_idx ] = (void *) timeout;
+
+	return argv;
+}
+
+
+void slurm_auth_free_args( void **argv )
+{
+	xfree( argv );
+}
+
 
 slurm_auth_context_t
 slurm_auth_context_create( const char *auth_type )
@@ -298,12 +346,12 @@ slurm_auth_init( void )
  */
 	  
 void *
-g_slurm_auth_create( void )
+g_slurm_auth_create( void *argv[] )
 {
 	if ( slurm_auth_init() < 0 )
 		return NULL;
 
-	return (*(g_context->ops.create))();
+	return (*(g_context->ops.create))( argv );
 }
 
 int
@@ -316,12 +364,12 @@ g_slurm_auth_destroy( void *cred )
 }
 
 int
-g_slurm_auth_verify( void *cred )
+g_slurm_auth_verify( void *cred, void *argv[] )
 {
 	if ( slurm_auth_init() < 0 )
 		return SLURM_ERROR;
 	
-	return (*(g_context->ops.verify))( cred );
+	return (*(g_context->ops.verify))( cred, argv );
 }
 
 uid_t
diff --git a/src/common/slurm_auth.h b/src/common/slurm_auth.h
index ddf2121a5c04b1c8cbc31e9dc2eccb1f08fb4ddf..91e8bb8a95a9b68c833064c46d00d5d23c2afdef 100644
--- a/src/common/slurm_auth.h
+++ b/src/common/slurm_auth.h
@@ -44,6 +44,7 @@
 
 #include "src/common/plugrack.h"
 #include "src/common/pack.h"
+#include "src/common/arg_desc.h"
 
 /*
  * This API operates on a global authentication
@@ -62,17 +63,49 @@
  *
  */
 
+/*
+ * General error codes that plugins (or the plugin system) can
+ * generate.  Plugins may produce additional codes starting with
+ * SLURM_AUTH_FIRST_LOCAL_ERROR.  They are responsible for providing
+ * text messages to accompany the codes.  This API resolves string
+ * messages for these codes.
+ */
 enum {
-    SLURM_AUTH_NOPLUGIN,
-    SLURM_AUTH_BADARG,
-    SLURM_AUTH_MEMORY,
-    SLURM_AUTH_NOUSER,
-    SLURM_AUTH_INVALID,
-    SLURM_AUTH_MISMATCH,
-
-    SLURM_AUTH_FIRST_LOCAL_ERROR	/* Always keep me last. */
+    SLURM_AUTH_NOPLUGIN,            /* No plugin for this type.          */
+    SLURM_AUTH_BADARG,              /* Bad argument to an API func.      */
+    SLURM_AUTH_MEMORY,              /* Problem allocating memory.        */
+    SLURM_AUTH_NOUSER,              /* User not defined on host.         */
+    SLURM_AUTH_INVALID,             /* Invalid credential.               */
+    SLURM_AUTH_MISMATCH,            /* Credential from another plugin.   */
+
+    SLURM_AUTH_FIRST_LOCAL_ERROR    /* Always keep me last. */
 };
 
+/*
+ * Text labels for advisory arguments passed to plugin functions.
+ * Use these labels rather than string literals in order to avoid
+ * misspellings.
+ */
+#define ARG_HOST_LIST		"HostList"
+#define ARG_TIMEOUT		"Timeout"
+
+/*
+ * Return the argument descriptor for the argument vectors in the
+ * plugin API.
+ */
+const arg_desc_t *slurm_auth_get_arg_desc( void );
+
+/*
+ * Marshal the arguments into a generic argument vector according to
+ * the authentication argument layout.
+ */
+void **slurm_auth_marshal_args( void *hosts, int timeout );
+
+/*
+ * Free an argument list created by slurm_auth_marshal_args().
+ */
+void slurm_auth_free_args( void **args );
+
 /*
  * SLURM authentication context opaque type.
  */
@@ -109,9 +142,9 @@ int slurm_auth_init( void );
 /*
  * Static bindings for the global authentication context.
  */
-void	*g_slurm_auth_create( void );
+void	*g_slurm_auth_create( void *argv[] );
 int	g_slurm_auth_destroy( void *cred );
-int	g_slurm_auth_verify( void *cred );
+int	g_slurm_auth_verify( void *cred, void *argv[] );
 uid_t	g_slurm_auth_get_uid( void *cred );
 gid_t	g_slurm_auth_get_gid( void *cred );
 int	g_slurm_auth_pack( void *cred, Buf buf );
diff --git a/src/common/slurm_protocol_api.c b/src/common/slurm_protocol_api.c
index b27ad805f4ddfe6af769dccda5d148a7388e47b4..58ae8d4ac46130ae1e24d98de968570754f7d050 100644
--- a/src/common/slurm_protocol_api.c
+++ b/src/common/slurm_protocol_api.c
@@ -334,6 +334,7 @@ int slurm_receive_msg(slurm_fd open_fd, slurm_msg_t * msg)
 	int rc;
 	void *auth_cred;
 	Buf buffer;
+	void **argv;
 
 	buftemp = xmalloc(SLURM_PROTOCOL_MAX_MESSAGE_BUFFER_SIZE);
 	if ((rc = _slurm_msg_recvfrom(open_fd, buftemp,
@@ -365,13 +366,21 @@ int slurm_receive_msg(slurm_fd open_fd, slurm_msg_t * msg)
 	}
 
 	/* verify credentials */
-	if ((rc = g_slurm_auth_verify(auth_cred)) != SLURM_SUCCESS) {
+	argv = slurm_auth_marshal_args( NULL, 2 );
+	if ( argv == NULL ) {
+		(void) g_slurm_auth_destroy( auth_cred );
+		free_buf( buffer );
+		slurm_seterrno_ret( SLURM_PROTOCOL_AUTHENTICATION_ERROR );
+	}
+	rc = g_slurm_auth_verify( auth_cred, argv );	
+	slurm_auth_free_args( argv );
+	if ( rc != SLURM_SUCCESS) {
 		error( "authentication: %s ",
 			   g_slurm_auth_errstr( g_slurm_auth_errno( auth_cred ) ) );
 		(void) g_slurm_auth_destroy(auth_cred);
 		free_buf(buffer);
 		slurm_seterrno_ret(SLURM_PROTOCOL_AUTHENTICATION_ERROR);
-	}
+	}	
 
 	/* unpack msg body */
 	msg->msg_type = header.msg_type;
@@ -430,9 +439,16 @@ int slurm_send_node_msg(slurm_fd open_fd, slurm_msg_t * msg)
 	unsigned int msg_len, tmp_len;
 	Buf buffer;
 	void *auth_cred;
+	void **argv;
 
 	/* initialize header */
-	auth_cred = g_slurm_auth_create();
+	argv = slurm_auth_marshal_args( NULL, 1 );
+	if ( argv == NULL ) {
+		error( "cannot marshal arguments to create credential" );
+		return SLURM_PROTOCOL_AUTHENTICATION_ERROR;
+	}	
+	auth_cred = g_slurm_auth_create( argv );
+	slurm_auth_free_args( argv );
 	if ( auth_cred == NULL ) {
 		error( "authentication: %s",
 			   g_slurm_auth_errstr( g_slurm_auth_errno( NULL ) ) );
diff --git a/src/plugins/auth/auth_authd.c b/src/plugins/auth/auth_authd.c
index f0bb01fcf6f5de36be371bf800c9c97a8b40f6a7..1bf933ba3afe478cfe717a5ca582607b7e13b34f 100644
--- a/src/plugins/auth/auth_authd.c
+++ b/src/plugins/auth/auth_authd.c
@@ -69,13 +69,20 @@
 #include "src/common/xassert.h"
 #include "src/common/pack.h"
 #include "src/common/log.h"
+#include "src/common/arg_desc.h"
 
 const char plugin_name[]	= "Brett Chun's authd authentication plugin";
 const char plugin_type[]	= "auth/authd";
 const uint32_t plugin_version = 90;
 
-/* Default life span of an authd credential in seconds. */
-static const int authd_ttl = 2;
+/*
+ * Where to find the timeout in the argument vector.  This is set
+ * during initialization and should not change.
+ */
+static int timeout_idx = -1;
+
+/* Default timeout. */
+static const int AUTHD_TTL = 2;
 
 typedef struct _slurm_auth_credential {
 	credentials cred;
@@ -231,22 +238,47 @@ slurm_auth_verify_signature( credentials *cred, signature *sig )
 	return rc_error;
 }
 
+
+int init( void )
+{
+	const arg_desc_t *desc;
+	
+	verbose( "authd authenticaiton module initializing" );
+
+	if ( ( desc = slurm_auth_get_arg_desc() ) == NULL ) {
+		error( "unable to query SLURM for argument vector layout" );
+		return SLURM_ERROR;
+	}
+
+	if ( ( timeout_idx = arg_idx_by_name( desc, ARG_TIMEOUT ) ) < 0 ) {
+		error( "Required argument 'Timeout' not provided" );
+		return SLURM_ERROR;
+	}
+	
+	return SLURM_SUCCESS;
+}
+
+
 slurm_auth_credential_t *
-slurm_auth_create( void )
+slurm_auth_create( void *argv[] )
 {
-	int ttl = authd_ttl;
-	slurm_auth_credential_t *cred = 
-		(slurm_auth_credential_t *)
+	int ttl;	
+	slurm_auth_credential_t *cred;
+
+	if ( argv == NULL ) {
+		plugin_errno = SLURM_AUTH_MEMORY;
+		return NULL;
+	}
+
+	cred = (slurm_auth_credential_t *)
 		xmalloc( sizeof( slurm_auth_credential_t ) );
 	cred->cr_errno = SLURM_SUCCESS;
-
-	/* Initialize credential with our user and group. */
 	cred->cred.uid = geteuid();
 	cred->cred.gid = getegid();
 
-	/* Set a valid time interval. */
 	cred->cred.valid_from = time( NULL );
 
+	ttl = timeout_idx >= 0 ? (int) argv[ timeout_idx ] : AUTHD_TTL;
 	/*
 	 * In debug mode read the time-to-live from an environment
 	 * variable.
@@ -260,7 +292,7 @@ slurm_auth_create( void )
 		}
 	}
 #endif /*NDEBUG*/
-	 
+
 	cred->cred.valid_to = cred->cred.valid_from + ttl;
 
 	/* Sign the credential. */
@@ -285,12 +317,12 @@ slurm_auth_destroy( slurm_auth_credential_t *cred )
 }
 
 int
-slurm_auth_verify( slurm_auth_credential_t *cred )
+slurm_auth_verify( slurm_auth_credential_t *cred, void *argv[] )
 {
 	int rc;
 	time_t now;
 
-	if ( cred == NULL ) {
+	if ( ( cred == NULL ) || ( argv == NULL ) ) {
 		plugin_errno = SLURM_AUTH_BADARG;
 		return SLURM_ERROR;
 	}
diff --git a/src/plugins/auth/auth_munge.c b/src/plugins/auth/auth_munge.c
index 2e8dc5ad953328f70ac2c5def9629c9eabfaa2d4..e532ee5fb229900be435fb5314b73e2775954941 100644
--- a/src/plugins/auth/auth_munge.c
+++ b/src/plugins/auth/auth_munge.c
@@ -62,6 +62,7 @@
 #include "src/common/pack.h"
 #include "src/common/log.h"
 #include "src/common/slurm_auth.h"
+#include "src/common/arg_desc.h"
 
 const char plugin_name[]       	= "auth plugin for Chris Dunlap's Munge";
 const char plugin_type[]       	= "auth/munge";
@@ -69,6 +70,8 @@ const uint32_t plugin_version	= 10;
 
 static int plugin_errno = SLURM_SUCCESS;
 
+static int host_list_idx = -1;
+
 enum {
 	SLURM_AUTH_UNPACK = SLURM_AUTH_FIRST_LOCAL_ERROR
 };
@@ -120,12 +123,10 @@ _decode_cred(char *m, slurm_auth_credential_t *c)
 
 int init ( void )
 {
-	/* 
-	 * Perhaps we could init a global context here? 
-	 * Do nothing for now.
-	 *
-	 */
-	return 0;
+	host_list_idx = arg_idx_by_name( slurm_auth_get_arg_desc(),
+									 ARG_HOST_LIST );
+	if ( host_list_idx == -1 ) return SLURM_ERROR;
+	return SLURM_SUCCESS;
 }
 
 
@@ -135,7 +136,7 @@ int init ( void )
  * data at this time is implementation-dependent.
  */
 slurm_auth_credential_t *
-slurm_auth_create( void )
+slurm_auth_create( void *argv[] )
 {
 	slurm_auth_credential_t *cred = NULL;
 	munge_err_t e = EMUNGE_SUCCESS;
@@ -189,7 +190,7 @@ slurm_auth_destroy( slurm_auth_credential_t *cred )
  * Return SLURM_SUCCESS if the credential is in order and valid.
  */
 int
-slurm_auth_verify( slurm_auth_credential_t *c )
+slurm_auth_verify( slurm_auth_credential_t *c, void *argv[] )
 {
 	if (!c) {
 		plugin_errno = SLURM_AUTH_BADARG;
diff --git a/src/plugins/auth/auth_none.c b/src/plugins/auth/auth_none.c
index 4c6202b56a375bc51e415a317ef7591ada4441e9..ad42369e7c749560f08d1ead64c31281c9d76c23 100644
--- a/src/plugins/auth/auth_none.c
+++ b/src/plugins/auth/auth_none.c
@@ -146,9 +146,10 @@ enum {
  * init() is called when the plugin is loaded, before any other functions
  * are called.  Put global initialization here.
  */
-void init ( void )
+int init ( void )
 {
 	debug("authentication==none");
+	return SLURM_SUCCESS;
 }
 
 /*
@@ -161,7 +162,7 @@ void init ( void )
  * NULL if it cannot allocate a credential.
  */
 slurm_auth_credential_t *
-slurm_auth_create( void )
+slurm_auth_create( void *argv[] )
 {
 	slurm_auth_credential_t *cred;
 
@@ -194,7 +195,7 @@ slurm_auth_destroy( slurm_auth_credential_t *cred )
  * Return SLURM_SUCCESS if the credential is in order and valid.
  */
 int
-slurm_auth_verify( slurm_auth_credential_t *cred )
+slurm_auth_verify( slurm_auth_credential_t *cred, void *argv[] )
 {
 	return SLURM_SUCCESS;
 }