Secrets API Draft
Secrets 0.1 DRAFT
StefWalterGNOME Keyring Developerstef@memberwebs.comMichaelLeupoldKWallet Developerlemma@confuego.org2008-2009The Secrets API AuthorsAPI DocumentationIntroductionThe Secrets API allows client applications to store secrets securily in a
service running in the user's login session. The secrets are usually stored in an encrypted manner by the service. The
service may need to be unlocked by the user before the secrets become available
for retrieval by client applications.The Secrets service stores a secret along with a set of lookup attributes.
The attributes can be used to lookup and retrieve a secret at a later date. The
lookup attributes are not treated as secret material, and the service may choose
to not encrypt attributes when storing them to disk.SecretsA secret is something an application wishes to store securely. A good example
is a password that an application needs to save and use at a later date.Within this API a secret value is treated as an array of bytes. It is
recommended that a secret consist of user readable text, although this API has
no such requirement.Applications wishing to store multiple values as part of a single secret, may
choose to use a textual format to combine these values into one. For example, the
'desktop' key file format, or XML or another form of markup.Secrets may be encrypted when transferred
to the client application and vice versa.The Secret structure encapsulates
a secret value along with its transfer encryption parameters.Collection and ItemsEach secret is stored together with
lookup attributes and a label. These together
form an item.A group of items together form a
collection.
A collection is similar in concept to the terms 'keyring' or 'wallet'.Collections and items are represented as DBus objects, and each have their own
object paths. The object path of a collection or item should not change for its lifetime,
under normal circumstances.It is strongly recommended that client applications use
lookup attributes to find items rather than
recording the object path of a stored item. This allows maximum interoperability.An item or a collection may be initially in a locked state. When in a locked
state the item or collection may not be modified in any way, and the secret may not
be read. Client applications that require access to the secret of a locked item, or
desire to modify a locked item, should unlock it before use.The service must prevent locked collections or items from modification. On
such an invalid access the
IsLocked
error should be raised.Client applications without special requirements should store in the default
collection. Use the
DefaultCollection
property on the Service interface to determine the default collection. In addition
the default collection is always accessible through a
specific object path.A new item can be created with the
CreateItem()
method on the Collection interface. When creating an item, the properties of the new
item are specified. The service may ignore or change these properties when creating
the item.When creating an item, the service may need to prompt the user for additional
information. In this case, a prompt object is returned. It
must be acted upon in order for
the collection to be created. In this case, the
result of the prompt
will contain the object path of the new item.An item can be deleted by calling the
Delete()
method on the Item interface.When deleting an item, the service may need to prompt the user for additional
information. In this case, a prompt object is returned. It
must be acted upon in order for
the item to be deleted.Client applications with special needs can create a new collection by calling the
CreateCollection()
method on the Service interface. When creating a collection, the properties of the new
collection are specified. The service may ignore or change these properties when creating
the collection.When creating a collection, the service may need to prompt the user for additional
information. In this case, a prompt object is returned. It
must be acted upon in order for
the collection to be created. In this case, the
result of the prompt
will contain the object path of the new collection.A collection can be deleted by calling the
Delete()
method on the Collection interface.When deleting a collection, the service may need to prompt the user for additional
information. In this case, a prompt object is returned. It
must be acted upon in order for
the collection to be deleted.Lookup AttributesAttributes can and should be stored with a secret to facilitate lookup
of the secret at a later date.An attribute constists of a name, and a value. Both parts are simple
strings.The service may have additional requirements as to what can be present
in an attribute name. It is recommended that attribute names are human
readable, and kept simple for the sake of simplicity.During a lookup, attribute names and values are matched via case-sensitive
string equality.It's important to remember that attributes are not part of the secret.
Services implementing this API will probably store attributes in an unencrypted
manner in order to support simple and effecient lookups.In order to search for items, use the
SearchItems()
method of the Service interface. The matched items will be returned in two sets. The
unlocked return value will contain the object paths
of all the items that are not locked. The locked return
value will contain object paths of items that are locked, which can be
unlocked if desired.The
SearchItems()
method of the Collection interface is similar, except for it only searches a single collection.SessionsA session is established between a client application and a service. A session
is used to transfer secrets between the client
application and the service.A session is established by calling the service's
OpenSession()
method. Once established, a session is bound to calling application's connection to
the DBus session bus.A session is closed when the client application disconnects from the DBus
session bus. Alternatively the client application can call the
Close()
method on the session interface. Once a session is closed all session specific
negotiations will be dropped by the service.More than one session may opened by a client application, although this is
not normally necessary.Transfer of SecretsTo access or store secrets, use the
GetSecret(),
GetSecrets(),
SetSecret()
methods on the session interface.Since this is a D-Bus API, the data in all method calls and other accesses
in this API will go through multiple processes, and may be cached arbitrarily
by the OS or elsewhere.The Secrets API has provision to encrypt secrets while in transit between
the service and the client application.The encryption is not envisioned to withstand man in the middle attacks, or
other active attacks. It is envisioned to minimize storage of plain text secrets
in memory and prevent storage plain text storage of secrets in a swap file or other
caching mechanism.Many client applications may choose not to make use of the provisions to
encrypt secrets in transit. In fact for applications unable to prevent their own
memory from being paged to disk (eg: Java, C# or Python apps), transfering
encrypted secrets would be an excersize of questionable value.This API was desigened by GNOME and KDE developers with the goal of having
a common way to store secrets. Its predecessors are the desktop specific APIs
used by GNOME Keyring and KWallet.Negotiation of AlgorithmsIn order to encrypt secrets in transit, the service and the client
application must agree on an algorithm, and some algorithm specific
parameters (eg: a key).The client application opens a session
with the service, and then calls the
Negotiate() method on that session. The algorithms argument to the
Negotiate() method specifies a set of algorithms to be used together for
key agreement and encryption. The other arguments are algorithm specific.If a service does not support a specific set of algorithms, a
NotSupported
error is returned, and the client is free to try another set of algorithms.
The plain algorithm is almost always supported.An algorithm may require that the Negotiate() method is called multiple
times in succession to be complete. Each iteration transfers algorithm specific
data back forth between the service and the client.Once an algorithm has been negotiated, it is used for all transfer of secrets
between the service and the client application in both directions. Algorithm
specific parameters may be transfered with each
secret.Algorithm: plainAlgorithm stringNegotiate inputNegotiate outputSecret parameterplainempty stringempty stringempty stringThe plain algorithm does no encryption whatsoever.It is strongly recommended that a service implementing this API support
the plain algorithm.Algorithm: dh-ietf1024-aes128-cbc-pkcs7Algorithm stringNegotiate inputNegotiate outputSecret parameterdh-ietf1024-aes128-cbc-pkcs7client dh pub key as an array of bytesservice dh pub key as an array of bytes16 byte AES initialization vectorTODO: DocumentLocking and UnlockingSome items and/or collections may be marked as locked by the service.
The secrets of locked items cannot be accessed. Additionally, locked items or collections
cannot be modified by the client application.It's up to the service whether to unlock items individually, or collections as a
whole. The client application should act as if it must unlock each item individually.A service may upon unlocking a collection, unlock all items in that collection. If
a service is not able to unlock an item individually, it should treat a request to unlock
an item as a request to unlock the connection that the item is in.A service may choose to unlock items or collections just for a single client
application. Alternatively the service may choose to allow any client application to access
items or collections unlocked by a another client application.A client application should always be ready to unlock the items for the secrets
it needs, or objects it must modify. It must not assume that an item is already unlocked
for whatever reason.A service may lock previously unlocked items for any reason at any time. Usually this
is done in response to user actions, timeouts, or external actions (such as the computer
sleeping). The inherent race conditions present due to this are unavoidable, and must be
handled gracefully.In order to unlock an item or collection the service's
Unlock()
method is called with one or more DBus object paths of items or collections. The
Unlock() will return the DBus object paths of objects it could
immediately unlock without prompting.The Unlock() method may also return a
prompt object. If a prompt
object is returned, it must be acted upon in order to complete
the unlocking of the remaining objects. The
result of the prompt
will contain the object paths that were successfully unlocked by the prompt.In order to lock an item or collection the service's
Lock()
method is called with one or more DBus object paths of items or collections. The
Lock() will return the DBus object paths of objects it could
immediately lock without prompting.The Lock() method may also return a
prompt object. If a prompt
object is returned, it must be acted upon in order to complete
the locking of the remaining objects. The
result of the prompt
will contain the object paths that were successfully locked by the prompt.Prompts and PromptingIn order to complete various operations, such as unlocking a collection, the
service may need to prompt the user for additional information, such as a master password.The prompts are displayed by the service on behalf of the client application.Operations that require a prompt to complete will return a prompt object. The client
application must then call the
Prompt()
method of the prompt object to display the prompt. Client applications can use the
window-id
argument to display the prompt attached to their application window.Once the user provides the additional required information to the prompt, the service
completes the operation that required the prompt. Then it emits the the
Completed
signal of the prompt object. The result argument of
the signal contains operation an operation specific result.Either the user or the client application can dismiss a prompt. In this case the
operation that required the additional information is cancelled. The client application
can dismiss a prompt by calling the
Dismiss()
method of the prompt object. The Completed signal will be emitted
with its dismissed argument set to
TRUE.Once the Completed signal is emitted on a prompt object, it
is no longer valid. Prompt objects are specific to the client application's connection
to the DBus bus. Once an application disconnects, all its prompts are no longer valid.There is an inherent race between the Dismiss() method and the
Completed signal. An application calling Dismiss()
must be prepared to handle the fact that the Completed has already been
emitted (although perhaps not received by the client). In addition the client must be prepared
to handle the fact that the prompt object is no longer valid.What's not included in the APIA service may implement additional DBus interfaces for further capabilities not
included in this specification. Password management applications or other narrowly
focused tools should make use of these when necessary.This specification does not mandate the use of master passwords to lock a
collection of secrets. The service may choose to implement any method for locking
secrets.This specification does not mandate any form of access control. The service may
choose to allow certain applications to access a keyring, and others.[TODO: complete]Notes for Service Implementors[TODO: complete]D-Bus API ReferenceObject PathsThe various DBus object paths used with the Secrets API are designed to be human
readable but not displayed to the user. The object path of an item or collection should
not change for its lifetime, under normal circumstances./org/freedesktop/secretsThe object path for the service./org/freedesktop/secrets/collection/xxxxThe object path for a collection, where xxxx represents a
possibly encoded or truncated version of the initial label of the collection./org/freedesktop/secrets/collection/xxxx/iiiiThe object path for an item, where xxxx is the collection (above)
and iiii is an auto-generated item specific identifier./org/freedesktop/secrets/session/ssssThe object path for a session, where ssss is an auto-generated
session specific identifier./org/freedesktop/secrets/defaultThe default collection for client applications to store secrets is available under
this object path in addition to its real object path (above).