aarc-community / architecture-guidelines

2 stars 0 forks source link

Consider additional public key types #7

Open marcvs opened 5 months ago

marcvs commented 5 months ago

we have ssh_public_key, how about gpg_public_key?

marcvs commented 2 months ago

And in general, I see this pattern with contact types (email, skype, googlemail, ...):

c00kiemon5ter commented 2 months ago

I think that we should be thinking in terms of how these keys are used. Not based on the fact that they are "keys".

I do not care about the user's "keys". I care about particular data that I use for a specific purposes.

Instead of the proposed options, I would go for something like this:

"server_access_keys": [
  {
    "type": "ssh",
    "value": "ssh-ed25519 AAAAC3NzaC1l..."
  }
],
"email_signing_keys": [
  {
    "type": "gpg",
    "value": "rsa3072/0xE89B3987AEB6032B"
  },
  {
    "type": "gpgsm",
    "value": "00BF8D25520C165CE0CE6735BDCAD333E3"
  }
]
"commit_signing_keys": [
  {
    "type": "gpg",
    "value": "rsa3072/0xE89B3987AEB6032B"
  }
]

Following this approach, users do not have to reveal all of their keys - a bag of things. But can choose specifically what is revealed to a service. A user looking at a UI page can fill in values for keys that are going to be used for specific purposes, instead of filling in keys that are is unclear how and when they will be used. The service does not need to do additional filtering to understand what it needs from a bag of things - it can request and use the key it needs for a particular purpose.

Being explicit, rather than implicitly trying to figure out what can or should be used.

marcvs commented 1 month ago

I like the idea, but not the approach: Yes being explicit is likely better than implicit. But: defining all these new types seems like overkill. How about:

{
  "public_keys": [
    {
      "type": "ssh",
      "value": "ssh-ed25519 AAAAC3NzaC1l...",
      "usage": "remote_access"
    },
    {
      "type": "gpg",
      "value": "rsa3072/0xE89B3987AEB6032B",
      "usage": "email_signing"
    },
    {
      "type": "gpgsm",
      "value": "00BF8D25520C165CE0CE6735BDCAD333E3"
      "usage": "email_signing"
    },
    {
      "type": "gpg",
      "value": "rsa3072/0xE89B3987AEB6032B",
      "usage": "commit_signing"
    }
  ]
}
zachmann commented 1 month ago

In your example @marcvs would it be better to have the following:

{
  "public_keys": [
    {
      "type": "ssh",
      "value": "ssh-ed25519 AAAAC3NzaC1l...",
      "usage": ["remote_access"]
    },
    {
      "type": "gpg",
      "value": "rsa3072/0xE89B3987AEB6032B",
      "usage": ["email_signing", "commit_signing"]
    },
    {
      "type": "gpgsm",
      "value": "00BF8D25520C165CE0CE6735BDCAD333E3"
      "usage": ["email_signing"]
    }
  ]
}

Anyway, I don't think that this addresses Ivans point. Since its still a bag of keys, filtering is now easier, but you still always get (and ask for) the whole bag and then have to filter it for e.g. email_signing.

c00kiemon5ter commented 1 month ago

We may need to set a few guiding questions to help us evaluate different formats, ie:

From my point of view, I don't see what we gain by having one generic attribute. It mixes intents and blurs use-cases. Introducing a change or a small deviation, has unforeseen effects as you cannot be sure how others use this attribute and what information they derive from it. Additionally, we try to make all possible representations of keys and their usages fit one model. For example, how would we express that a certain key is used for "signing emails" for a particular email-address? Once we start digging into the use-cases for these keys, differences will start popping up. And then we either compromise, or create a complex structure, or have optional fields and based on their presence we derive the use-cases. It is going to be a mess.

IMO, this is the same mistake we did with entitlements. In practice, what I see that it is hard to work with such a generic attribute. To do anything that involves entitlements, you need to parse all of them and then filter them and then derive some result. This has proven hard for services. Using that format as an exchange between proxies may work. But putting this complexity on services, in practice, is harder that initially expected.

If the problem the need to define the different attributes, I think that's exactly what we as AARC should be doing. The complexity is inherently there. What we are doing is moving it around. In the end something has to deal with it. As AARC, I think the premise is that proxies take on the complexity, no matter if this complexity is technical or not.

Releasing specific attributes for specific usages is simple from the perspective of services and users. The proxies take on the complexity of filling in this information and exchanging it within a network of proxies. AARC takes on the complexity of defining the attributes, their semantics and the expected use. Having clear guidelines for specific use-cases.