Making user secrets interoperable between applications and accessible by authorized applications.
pinging the maintainers of gnome-keyring and libsecret to engage discussion and find the best way to achieve this, namely @dueno and @nielsdg.
All this proposal is taking as basis sandboxed applications (flatpak in this case) since we cannot do much in the way of authenticating accuratly applications (needed for permissions) and anyway we can't block access or filter dbus without sandbox.
What we currently have
I have not put details on the functionning of the secret portal as it's not useful to know to understand this diagram.
As you can see, all the browsers store the user's credentials for a website locally (in the sandbox) and with their own schema to store them. This means that
- browsers can't access directly to user's credentials stored in the keyring, so the user needs to copy the credentials to each browser individually (left part of the diagram).
- Even if they could access user's credentials for this website, they don't store it the same way (green boxes on the right).
- If they can access user's credentials, we need some kind of permission at the level of flatpak so they can only access a group/category of passwords that are relevant for this specific application.
What I propose
- make available a full secrets API interface provided by the portal on org.freedesktop.secrets and blacklist from the host every dbus talk name that provides "org.freedesktop.secrets". This might seems stupid, but we really spoof applications. By default, the portal's secrets API would handle local storage and access of secrets (basically, the same as the secrets portal does when using the simple API of libsecret). However, we make available a new dbus function on object org.freedesktop.Secret.Session to enable host secrets for the session.
- Now the standard way of storing credentials. I propose to make a schema in libsecret available as SECRET_SCHEMA_URL like this (inspired from https://developer.gnome.org/libsecret/0.20/c-examples.html#c-schema-example) :
/* in a header: */
const SecretSchema * secret_schema_url_get (void) G_GNUC_CONST;
#define SECRET_SCHEMA_URL secret_schema_url_get ()
/* in a .c file: */
const SecretSchema *
secret_schema_url_get (void)
{
static const SecretSchema the_schema = {
"org.freedesktop.Secret.URL", SECRET_SCHEMA_NONE,
{
/* we expose the different parts of the URI (see https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Definition) with separated attributes to enable giving access to only protocol "irc" for example (permissions, later on point 3.) */
{ "protocol", SECRET_SCHEMA_ATTRIBUTE_STRING }, /* Required. "protocol" NOT "scheme" because this is the usual case and this schema isn't made to handle file:/// URI scheme */
{ "authority", SECRET_SCHEMA_ATTRIBUTE_STRING }, /* optionally filled */
{ "query", SECRET_SCHEMA_ATTRIBUTE_STRING }, /* optionally filled */
{ "fragment", SECRET_SCHEMA_ATTRIBUTE_STRING }, /* optionally filled */
{ "username", SECRET_SCHEMA_ATTRIBUTE_STRING }, /* this should be used when it is inappropriate to include it in the parts of the URI (not defined in the URI spec/RFC) for example the username for a website (there is no standard way of handling this but browser knows how to autofill when needed) */
{ "NULL", 0 },
}
};
return &the_schema;
}
By creating this standard schema for URLs, every applications will be able to access credentials for a same protocol (for example irc, https, matrix, imap/smtp). This also means we will be able to remove ugly application-specific code like https://gitlab.gnome.org/gnumdk/passbook/-/blob/master/passbook/define.py#L43 or https://gitlab.gnome.org/GNOME/seahorse/-/blob/master/gkr/gkr-item-info.vala#L50 and rather than saying "account mail@gmail.com for Geary" we could say "email account mail@gmail.com", without having to show the icon of the application (we can't get applications icon with flatpak so this would be one less problem to deal with).
- We can handle individual application permissions to access some type of secrets (http, imap, etc) because we have 1. and 2. . Because we spoof org.freedesktop.secrets with the portal and we have a function to have an out-of-sandbox secrets session, it is now possible to setup flatpak permissions. The columns that are available for
flatpak permissions
are "Table", which would be "secrets", "Object", which would be the collection object path, "App", which would be the app id of the application, "Permissions", which would be a comma separated list. Possible values are "store" (to add an item in the collection), "remove" (which wouldn't be granted to anything else than a password manager, though applications with access to all "foo" protocol items could still delete an item with user consent) and "lookup", "search" and probably "list". Those "Permissions" would apply to a scope of items, in the "Data" column, like "protocol=irc" for an IRC client or "protocol=*" for all items (this would only be granted with a prompt explaining the risks and user should only grant access to a password manager).
What we get after all this is done
- interoperability between applications
- per-application permissions for each protocol to have precise control over what is granted or not
In my opinion, the Prompt object and Unlock function are details that clients of the Secret API shouldn't have to deal with so I propose to just remove them and let the secret service do this job (there won't need to introduce breaking changes, just make those functions empty and deprecate them).
Tasks that will follow up once this is settled
-
introduce the secrets API spoofer and permissions in xdg-desktop-portal -
introduce the SecretSchemaURL in libsecret -
create a GNOME GoalInitiative to help application migrate to the new schema (existing application will still work but the keyring will be in the sandbox because they don't use the SecretSchemaURL so no breakage here)
So I would like to get feedbacks from @dueno and @nielsdg on my overall proposal that I have matured for more than a week now, documenting myself on the secrets API specs, libsecret and the secrets portal (though there wasn't much information out there but the conference of @dueno at GUADEC 2019 helped me a lot understanding). I know this is a lot to manage but I think it is worth it. And note that I will handle all the code once we have settled on a good overall concept together.
(and @gnumdk if you are willing to take part in the discussion)