WLCG-AuthZ-WG / common-jwt-profile

A repo for the WLCG Common JWT profile document
3 stars 8 forks source link

Limitation of the storage claim #22

Open chaen opened 1 year ago

chaen commented 1 year ago

This github issue aim at illustrating the limitation we would face with the current profile when it comes to storages.

Extract from the current profile

These here are just snippet of the JWT profile in its current form, on which I base my comments below

Audience statements:

https://github.com/WLCG-AuthZ-WG/common-jwt-profile/blob/84b8e2aafa3a1a01e03b101c906444a9b1a47bd5/profile.md?plain=1#L328-L333

https://github.com/WLCG-AuthZ-WG/common-jwt-profile/blob/84b8e2aafa3a1a01e03b101c906444a9b1a47bd5/profile.md?plain=1#L339

Path statements:

https://github.com/WLCG-AuthZ-WG/common-jwt-profile/blob/84b8e2aafa3a1a01e03b101c906444a9b1a47bd5/profile.md?plain=1#L468

Base path definition

https://github.com/WLCG-AuthZ-WG/common-jwt-profile/blob/84b8e2aafa3a1a01e03b101c906444a9b1a47bd5/profile.md?plain=1#L776-L791

Use case

Each LHCb user is given a logical grid directory in which he is allowed to upload files. It is of the form /lhcb/user/c/chaen. This directory exists on multiple sites.

The User StorageElements (SE) are defined as:

CERN-USER:
base_path = /eos/lhcb/prod/userarea/
GRIDKA-USER:
base_path = /pnfs/gridka.de/lhcb/userarea/
RAL-USER:
base_path = lhcb:user

A user file uploaded as the LFN /lhcb/user/c/chaen/toto.xml on the various StorageElements would end up in

CERN-USER: /eos/lhcb/prod/userarea/lhcb/user/c/chaen/toto.xml
GRIDKA-USER: /pnfs/gridka.de/lhcb/userarea/lhcb/user/c/chaen/toto.xml
RAL-USER: lhcb:user/lhcb/user/c/chaen/toto.xml

I want to issue a token that will allow the bearer to write on ALL the USER SEs

Problems

Problem with audience

The audience can in theory be a list. But if we have to list all the endpoints in the audience, the token will be huge, and we will very quickly reach the maximum header size.

Problem with the path definition

What is an absolute path ?

If the path is absolute from the storage point of view, the path should be the full physical path (i.e. /eos/lhcb/prod/userarea/lhcb/user/c/chaen/ or /pnfs/gridka.de/lhcb/userarea/lhcb/user/c/chaen/) but in that case, it is valid for one audience only.

The only sensible thing to do is to use the LFN as path: /lhcb/user/c/chaen/

But in that case, we end up with the problem of the base path definition mentioned just below.

Problems with base path definition

From a site point of view, each VO is given a base path in which the experiment can write and do anything. For example /eos/lhcb/ at CERN, /pnfs/gridka.de/lhcb at GRIDKA. This root directory is reflected in the configuration at the site for token validation

 [Issuer cms] 
 issuer = https://wlcg.example/cms 
 base_path = /users/cms 
 [Issuer dteam] 
 issuer = https://wlcg.example/dteam 
 base_path = /users/dteam 

However, from the experiment point of view, this root path is often further divided.

This division can be by related to the activity, for example:

Or it can even be divided by the various instances of the middleware, like the production and the certification instance of DIRAC:

The second case could be discarded by simply saying that each DIRAC instance should have a separate IAM instance (fair enough).

But the first case is legitimate and poses problem. If my token contains path:/lhcb/user/c/chaen and the storage knows only /pnfs/gridka.de/lhcb as base path, the permission obviously does not point to the directory I would like it to.

Proposal

Replace the storage.*:/path approach with something along these lines

{
  "aud": "storages",

  "storage.modify":{
    "path": "/lhcb/user/c/chaen",
     "ses": ["CERN-USER","GRIDKA-USER","RAL-USER"]
  }
}

Contrary to what is written in https://github.com/WLCG-AuthZ-WG/common-jwt-profile/blob/84b8e2aafa3a1a01e03b101c906444a9b1a47bd5/profile.md?plain=1#L339 user readable names are good because shorter (solve the header length issue). But indeed, you need a lookup table. You could imagine having this lookup table in a json file in the .well-known directory of the IAM instance in question (e.g. /.well-known/storage_definition.json)

The storage_definition.json could contain entries like:

  "USER-Storages": [
  {
    "base_path": "/eos/lhcb/prod/userdata",
    "host": "eoslhcb.cern.ch"
  },
  {
    "base_path": "/pnfs/gridka.de/lhcb/userarea/",
    "host": "lhcb-gridka.fzk.ch"
  }
]

This allows even more generic token like "do anything in your user area and read all the production data"

{
  "aud": "storages",
  "storage.*": {
    "path": "/lhcb/user/c/chaen",
    "ses": "USER-Storages"
  },
  "storage.read": {
    "path": "/",
    "ses": "PROD-Storages"
  }
}

And of course, storage can make sure that the path defined in the storage_definition.json file start with the base_path they have configured.

Note that the SE definitions do not often change, so the storage systems can do aggressive caching of the definitions to validate tokens faster.

Extra bonus with this format: a token allowing third party copy between two SE could be directly handed to FTS (so no token exchange needed from its side) and would look like

{
  "aud": "storages",
  "storage.read": {
    "path": "/lhcb/user/c/chaen/toto.xml",
    "ses": "SOURCE-SE"
  },
  "storage.write": {
    "path": "/lhcb/user/c/chaen/toto.xml",
    "ses": "DEST-SE"
  }
}
paulmillar commented 1 year ago

Sorry, I don't understand the problem you are facing from your description.

Audience claims Yes, you can have multiple values but this is not recommended. In the profile you can either specify a single target (i.e., a single storage element), or use a "wildcard" value to say the token should work on all storage.

Explicit AuthZ statements (scope claims) Could you provide a concrete example where the current JWT profile doesn't work? What file operation would you like to authorise and why doesn't it work?

chaen commented 1 year ago

Hi @paulmillar ! Please check the Use Case part. I give a very concrete example:

I want to issue a token that will allow the bearer to write on ALL the USER SEs

paulmillar commented 1 year ago

Sorry, your example is not really concrete, it's actually rather abstract.

For me, a concrete use-case is something like:

Each LHCb user is assigned their own (personal) subtree within the LHCb namespace at each SE. This is somewhere a user may store their personal (non-group) files without risk of clashing with similarly named files from other LHCb users.

A LHCb user with username "fbloggs" wishes to upload a file my-latest-results.root into their personal portion of the LHCb namespace. The token should authorize this upload on any LHCb storage element.

This personal namespace is a subdirectory within a portion of the LHCb namespace used to store all LHCb users' personal subtrees.

For example, the personal subtree of the user "fbloggs" at storage element SE-1 is the directory f/fbloggs/, relative to some directory dir-X/ (where dir-X is a placeholder value). Similarly, another user "chaen" at the same storage element (SE-1) has a personal subtree under the directory c/chaen/, relative to the same directory (dir-X/). This is true for all LHCb storage elements, although the path dir-X/ will (in general) be different on different storage elements.

In general, the directory for all LHCb users' personal storage (the dir-X placeholder value, in above example) varies between different SEs.

For example, at CERN it is userdata/, at KIT it is userarea/, at RAL it is user/. These example paths are relative to some base path, which has been allocated for all LHCb storage. The base path (allocated for all LHCb storage) at KIT is /pnfs/gridka.de/lhcb/, the base path at CERN is /eos/lhcb/prod/, and the base path at RAL is lhcb:.

Discussion

If I understood the problem correctly (and the above use-case accurately describes the desired behaviour) then we have a few ways of supporting this.

  1. LHCb adopts a common approach to storing user's data.

If LHCb (quite reasonably) would like uniform behaviour then it should lay out files in a uniform way. This would require LHCb to undergo a storage reorganisation campaign. IMHO, this is not unreasonable as other VOs have undertaken similar reorganisation campaigns.

  1. Give up on the requirement that a token should work on all SEs.

It may be desirable for a token to be "tied down" so it can only work with a specific storage element. This is purely for security considerations: limiting the damage if the token is "stolen" (leaked). If this is done then the problem goes away: the token can contain the correct authorisation path for the targeted storage element.

  1. Storage software support more sophisticated AuthZ mapping.

The mapping between the "authorisation path" (i.e., the path /foo/bar from the explicit AuthZ statement storage.modify:/foo/bar) and the storage namespace (the directory into which files are upload; e.g., /pnfs/gridka.de/lhcb/foo/bar) is not specified in the JWT profile.

At least in dCache, this mapping currently assume a simple prefix: all AuthZ paths are resolved against a common base path to determine the namespace path (e.g., storage.modify:/foo/bar authorises writing into /pnfs/gridka.de/lhcb/foo/bar, by resolving the AuthZ path against a common base path of /pnfs/gridka.de/lhcb).

So, one solution could be for storage elements to provide a more sophisticated AuthZ-to-namespace mapping.

To be more concrete, one way to do this is to support a placeholder initial path-element in the AuthZ path to represent the LHCb user-space base path.

For example, the token would have a scope claim that contains storage.modify:USERS/f/fbloggs. The path element USERS is a placeholder value that maps to /eos/lhcb/prod/userdata/ at CERN, and maps to /pnfs/gridka.de/lhcb/userarea/ at KIT, etc.

In this way, an AuthZ statement would work in a uniform way across storage elements, despite the transfer namespaces being non-uniform.

Personally, I would prefer 1. or 2. over 3 to avoid unnecessary complexity in the storage (my own self-interest ;-). However, all three options would solve the LHCb user data access without requiring any changes to the JWT profile.

paulmillar commented 1 year ago

Just to add some further thoughts:

There may be other solutions to this problem that are supported by the JWT profile. The above three are just the ones I could think of :-)

Of course, we can modify the JWT profile to support the LHCb use-case (in line with @chaen 's suggestion). However, I think we should first explore the above options and understand why are not possible.

Finally, the first option ("1. LHCb adopts a common approach to storing user's data") might not be too bad, at least for "regular" (non-object-store) storage. Such a move (to adopt a WLCG-wide canonical convention) could involve renaming a directory and adding a symbolic link for backwards compatibility. This could be done (more or less) atomically. Existing references would continue to work (via the sym-link).

chaen commented 1 year ago

Hi @paulmillar Sorry for the silence, I was off since I wrote this issue :-) You perfectly understood the problem, but you are obviously better than me at expressing it :-)

1. LHCb adopts a common approach to storing user's data.

that seems like a fair suggestion, and I am totally willing to do it (I sort of had it in mind already :-)).

I am not entirely sure that it solves everything though. For example, we have storages with and without user space. How should I generate a token allowing me to read from all storages, but only write to storages with a user space ?

Also you mention

Finally, the first option ("1. LHCb adopts a common approach to storing user's data") might not be too bad, at least for "regular" (non-object-store) storage.

RAL is already a special case, and that alone is a reason to consider a broader scope from the beginning.

In the case of a uniform namespace, the question I raise about the path definition has an answer: what goes in path should be <placeholder>/<LFN>.

2. Give up on the requirement that a token should work on all SEs.

That is a matter of trade of between security and operational aspects. We can do a very detailed risk assessment but a token allowing a user to write to his own user space only (and not to his colleague's) is already a huge improvement compared to proxies. And we consider this a good middle ground. So we are not willing to give up on that. There is another aspect not to forget (I don't want to multiply the examples here though): applications may be talking to multiple storages at once (think of hadd for example). So we need a generic way to express that.

3. Storage software support more sophisticated AuthZ mapping.

Your proposal of having a place holder in the path is interesting. It basically boils down to having the logical storage element definition on the storage itself, and not in a centralized dynamic json like I mentioned.

In a way, this is closer from what cloud provider (and RAL!) do: you not only write to an endpoint, but you also specify a bucket.

I think that would solve a lot of issues in how we express permissions.

I see 2 drawbacks (if we may even call it that):

vokac commented 1 year ago

For Third-Party-Copy you can generate two independent tokens for source and destination storage (they could be even cached and reused by FTS). Originally our FTS design used just one token for whole FTS TPC transfer (current implementation), but I always thought it would be better to use two independent tokens, because on one side it is sufficient to use storage.read while the other side needs privileges for writing.

msalle commented 1 year ago

For Third-Party-Copy you can generate two independent tokens for source and destination storage (they could be even cached and reused by FTS). Originally our FTS design used just one token for whole FTS TPC transfer (current implementation), but I always thought it would be better to use two independent tokens, because on one side it is sufficient to use storage.read while the other side needs privileges for writing.

but the source will need both tokens: it needs to receive the read token but also be able to send the write token. Only the destination needs just the write token?

vokac commented 1 year ago

For Third-Party-Copy you can generate two independent tokens for source and destination storage ...

but the source will need both tokens: it needs to receive the read token but also be able to send the write token. Only the destination needs just the write token?

Yes, both tokens are available for active TPC party, but only one token reach passive party.

HTTP-TPC pull: active party is destination storage which GET data from source (read token) HTTP-TPC push: active party is source storage which PUT data to the destination (write token)

Compromised tokens gives write privileges to one storage, not both as in case of token with read+write scope and two audiences

{
  "wlcg.ver": "1.0",
  "sub": "84622f21-a31a-46b9-81b4-85e7841e1695",
  "aud": "https://active-tpc-party.example.com,https://passive-tpc-party.example.com",
  "nbf": 1670576459,
  "scope": "storage.modify:/transfer/destination/path storage.read:/transfer/source/path",
  "iss": "https://atlas-auth.web.cern.ch/",
  "exp": 1670580059,
  "iat": 1670576459,
  "jti": "129a07b0-d59c-4fb9-bd4d-e8d602d465a0",
  "client_id": "e9b44f9d-c745-4860-bedc-dbb2c9a82fba"
}

E.g. if one storage is compromised than HTTP-TPC pull mode still prevent data destruction on the rest of distributed storage infrastructure.

maarten-litmaath commented 1 year ago

Hi all, for storage, the WLCG profile is only concerned with a VO's namespace under an SE-specific path prefix.

Though historically, the VO probably needed to know and include such prefixes more often than not, with tokens we have an opportunity to do away with such encumbrances.

During the transition period, legacy methods (X509 + VOMS) should continue being able to use legacy (i.e. full) paths, while for tokens, each SE should be configured to add VO prefixes implicitly.

W.r.t. targeting multiple SEs with a single token, it is true that any damage from an abused token can be limited to the path(s) explicitly listed. However, in the case at hand, a VO probably would not want user directories to be created on a tape SE! The VO data management client SW should not propose such SEs to random users, of course, but we would like it better if such attempted operations would be guaranteed to fail. Unfortunately this clashes with the wish for leading directories to be created automatically as needed. As a compromise, we could forbid such automatic creations in the root directory of the VO, i.e. at least the primary leading directory (e.g. "/users") should already exist...

vokac commented 1 year ago

Do you expect that all storage endpoints should always provide path starting with VO prefix, e.g. /atlas and that we should not accept in future arbitrary prefixes like /dpm/cern.ch/home/atlas or /eos/atlas?

Second issue with tokens that can create e.g. /vo/users on all SEs was also discovered by other experiments (e.g. ATLAS, CMS), because just limited number of SEs in our infrastructure really provide dedicated space for e.g. local users or physic groups. I think the question is if this should be part of WLCG profile & implemented by each SE or we just need more flexible policies in the token provider to allow tokens with storage.modify:/users scope only for specific aud content.

maarten-litmaath commented 1 year ago

Hi Petr, I think it would be the nicest if the root directory for a VO were just "/" instead of "/VO_name", but the latter convention would allow one VO to access data from another, should that be necessary for some use case...

On your second point, we would need to discuss with the IAM (and CILogon) devs to see if support for such restrictions can be implemented without too much hassle. And if so, decide if such usage is going to be a sustainable way for a typical VO to limit what can be done on particular sets of SEs. For example, the VO might need to list many SE names explicitly for various use cases: not nice... It would be easier if there were support for prohibitions as well. For example, storage.modify:/users is not permitted on a given set of tape SEs... Given those various potential complications, it might be more practical just to forbid automatic primary directory creation instead.

paulmillar commented 1 year ago

Do you expect that all storage endpoints should always provide path starting with VO prefix, e.g. /atlas and that we should not accept in future arbitrary prefixes like /dpm/cern.ch/home/atlas or /eos/atlas?

Let's say there are three storage systems that provide storage capacity to ATLAS. They each provide this storage under different paths: /pnfs/desy.de/atlas, /dpm/cern.ch/home/atlas and /eos/atlas. A token with a scope claim value containing storage.modify:/foo would allow the bearer to modify files under /pnfs/desy.de/atlas/foo on the first storage system, modify files under /dpm/cern.ch/home/atlas/foo on the second storage system and modify files under /eos/atlas/foo on the third storage system.

In general, there is a VO-specific prefix (e.g., /dpm/cern.ch/home/atlas). The "authorisation path" (e.g., /foo in storage.modify:/foo) is resolved relative to this VO-specific prefix. This VO prefix is potentially different for different storage services and it's something the VO has (somehow) to know. However, this is no different to what the VO needs to know currently.

I'm assuming that if a storage system provides storage capacity for other VOs then they do so under a different path (for example, /pnfs/desy.de/cms, /dpm/cern.ch/home/cms and /eos/cms for the three example storage services above). If so, then the ATLAS token would never grant any access to that other VOs storage capacity. It doesn't matter what prefixes are placed in the ATLAS token's scope claim: an ATLAS token can never grant access to CMS storage.

maarten-litmaath commented 1 year ago

Hi Paul, the fact that VOs have needed to know those prefixes for legacy access does not imply they will need to continue to know them for the use of tokens. By your own argument (and according to our profile), storage.modify:/foo applies to /foo below the prefix (a.k.a. root directory) for the VO in question. Therefore, the prefix might as well be opaque and we should aim for that to happen with tokens. That said, we might prefer the VO namespace to start at "/VO_name" instead of "/" to allow data to be shared between VOs... Am I missing something?

paulmillar commented 1 year ago

the fact that VOs have needed to know those prefixes for legacy access does not imply they will need to continue to know them for the use of tokens

While we may aspire to do better, the fact that VOs already handle per-SE prefixes means this is a solved problem. In other words, this isn't a show-stopper.

By your own argument (and according to our profile), storage.modify:/foo applies to /foo below the prefix (a.k.a. root directory) for the VO in question.

Yes. This is simply resolving the AuthZ path relative to per-VO prefix. In other words: /foo resolved-against /dpm/cern.ch/home/atlas --> /dpm/cern.ch/home/atlas/foo.

Therefore, the prefix might as well be opaque and we should aim for that to happen with tokens.

Currently (with VOMS and tokens), the request path reflect the "real" path within the storage system; for the /dpm/cern.ch/home/atlas/foo example, this might be:

curl -L -T my-output.root -H "Authorization: Bearer $MY_JWT" https://dpm.example.org/dpm/cern.ch/home/atlas/foo/my-output.root

IIRC, the JWT profile doesn't mention any changes to the request path (the /dpm/cern.ch/home/atlas/foo/my-output.root in above example).

If I've understood your comment, you are suggesting that the request path should avoid the prefix. Following this idea, the above example curl command would be:

curl -L -T my-output.root -H "Authorization: Bearer $MY_JWT" https://dpm.example.org/foo/my-output.root

I think this only makes sense if it is done for all token-based requests (including request made with tokens that have no explicit AuthZ statements). Currently, services are free to ignore explicit AuthZ statements (using group-membership instead). Therefore, we would only get consistent behaviour if this mapping were done for all token-based requests.

As it happens, dCache allows the admin to configure a per-user, chroot-like path. When this feature is enabled, all requests from that user are interpreted relative to some prefix (with no possibility to escape). If so configured, an ATLAS user could upload a file targeting the /foo/my-output.root path and dCache would store that file as /pnfs/desy.de/atlas/foo/my-output.root. All other operations (download, directory listing) work similarly; in other words, the user never knows that they are working within a sub-tree of dCache's namespace.

The dCache instance may be configured so that CMS users experience a different chroot path. Therefore, a CMS user (on the same dCache instance) could make the same request (targeting /foo/my-output.root) but using a CMS token. The file would be stored as /pnfs/desy.de/cms/foo/my-output.root.

So, this is possible with dCache.

However I don't know if this would be supported by all storage systems. Also, it would require some kind of campaign, where this change is enacted SE-per-SE, with corresponding changes in the VO catalogues: a non-trivial effort. Therefore, I think this is something would require more discussion.

This is also rather tangential. It is (perhaps) a nice-to-have feature, but I don't see this as a show-stopper. We could do this after AuthZ tokens are in use.

That said, we might prefer the VO namespace to start at "/VO_name" instead of "/" to allow data to be shared between VOs... Am I missing something?

Well, technically you're right: this is possible. We can choose any (self-consistent) mapping between AuthN namespace and the filesystem namespace.

However, a couple of things you might like to consider.

  1. I believe we deliberately avoided talking about multi-VO use-cases. If we want to include this (particularly in a single token) then (IMHO) it needs a much broader discussion than taking only about the AuthN namespace.
  2. An alternative approach for someone who's a member of two VOs is to have two tokens: one from each of the VO's OP; for example, use the CMS token when interacting as a member of CMS and the ATLAS token when interacting as a member of ATLAS. While slightly more awkward for the user, it is conceptionally much simpler and would work with the existing JWT profile.
  3. Having a single token that asserts information from multiple VOs breaks our assumption that each VO has its own OP (should the CMS OP start asserting that someone can access ALICE files?). This would require a strong trust relationship between all VOs, and would require quite some effort to implement.

Expanding on the first point, all VO-related information (group-membership, SE AuthZ, CE AuthZ, etc) would need the token to identify for which VO they apply. Currently the VO is clear: a token issued by the ATLAS OP asserts ATLAS-related information (the asserted groups are ATLAS groups, the asserted AuthZ statements apply to ATLAS resources, etc). If we have a multi-VO tokens then a token could include information (group-membership, AuthZ statements) about CMS and about ALICE and DUNE and ...

To my mind, this breaks the JWT profile, as its currently written: the document provides no standard way for a token to describe for which VO a particular group or AuthZ statement applies.

Interestingly, the group-membership syntax coming from AARC (AARC-G02, IIRC) includes a group namespace concept. This would allow a single token to assert both CMS- and ATLAS group-membership. If we really want to support multi-VO tokens then adopting the AARC group-membership representation would be one possible solution.

That still leaves the AuthZ statements, which would need to identify for which VO's resources the AuthZ statement applies. We can do this in an ad-hoc fashion (e.g., by adding the VO in the AuthZ path), but a better approach might be to reconsider the syntax and provide a more general solution: one that could work for computing resource AuthZ statements, too.

So, yes, we could add the VO name in the AuthZ path. However, we should think really really hard before doing so.

chaen commented 8 months ago

Coming back on that after a long time, and discussions with multiple people (e.g Rucio/IAM dev) and other experiments.

Whether we like it or not, namespaces will not be uniform across storages (again confiremd by discussions during the DC workshop):

So the assumption namespace is uniform does not hold, and we can't rely on it (nor DIRAC nor Rucio)

After discussing with Rucio/IAM people, I would like to propose a much lighter approach to solve that.

What DIRAC/Rucio store in the config is

"DESY-SCRATCH"
{
    "prefix" : "/pnfs/desy.de/atlas/scratch/"
}
"CERN-SCRATCH"
{
    "prefix" : "/dpm/cern.ch/home/atlas/anythinggoes/"
}

Currently, if I want to read an LFN called myFile.root, I need a token that specified

For DESY

"storage.read:/scratch/mylfn.root"

FOR CERN

"storage.read:/anythinggoes/mylfn.root`"

so basically you need to put as path <prefix-voroot>/<lfn>

Not only is voroot not necessarily known (and even if we can get it, that's yet another info which is not yet part of DIRAC/Rucio config) but we saw it breaks across non uniform namespace.

At the storage level, if I understand properly, what is done is just to make sure that the issuer is allowed operation in <voroot / path_in_token> (which boils down to <prefix / lfn>)

From the semantic point of view, for DIRAC/Rucio, prefix or voroot are meaningless. What we want is to act on a given LFN stored in a SCRATCH space, be it specifically at DESY, or specifically at CERN, or in any of the two.

You could express it like

storage.read:$SCRATCH$/mylfn.root

and if you specifically want CERN or DESY, you can use the audience to restrict it.

And this is the addition I would like to propose. It's not a change, it's an addition. Support these area alias like $SCRATCH$

This would allow to very easily support non uniform namespaces, without breaking the existing functionality.

From the storage point of view, the parsing would not be very different to what is already implemented.

What is required though is the propagation of the information of what $SCRATCH$ corresponds to at the various sites, such that the storage have access to this information.

The best place would be a .well-known/se-configuration endpoint in the issuer.

"CERN":
{
   "SCRATCH" : "/dpm/cern.ch/home/atlas/anythinggoes/",
   "MC": "/dpm/cern.ch/home/atlas/mcdata/",
   "USER": "/dpm/cern.ch/home/atlas/user/",
},
"DESY":
{
  "SCRATCH" : "/pnfs/desy.de/atlas/scratch/",
   "MC":  "/pnfs/desy.de/atlas/mcdata/"
}

I believe that this is a minor addition, but which solves a lot of issues.

cc: @giacomini, @bari12, @dchristidis

msalle commented 8 months ago

I'm probably missing something important but why isn't anything under the VO namespace (so after let's say /pnfs/desy.de/atlas for DESY and /dpm/cern.ch/home/atlas for CERN) completely up to the VO? Personally I also think it MUST be the same for each SE, if it isn't I don't understand why not, at least not from the perspective of our profile.

Trying to impose things like $HOME, $TMP, etc on top of a VO prefix seems like unnecessary complications that shouldn't be in the profile (if a VO wants to do that for its own namespace part that's not up to us of course).

chaen commented 8 months ago

Personally I also think it MUST be the same for each SE

The token profile comes 15 years after experiments started writing data. As a matter of a fact, discrepancies between SEs exist, and they wont be fixed

giacomini commented 7 months ago

We have discussed the matter between IAM/StoRM developers and StoRM deployers and our preference would be that the scope path prefix-matches the path in the URL, without any assumptions about the VO-based mapping, i.e. if you want to GET https://storage.example.com/vo/dir/file.txt the scope has to be storage.read:/vo/dir/file.txt or storage.read:/vo/dir or storage.read:/vo or storage.read:/. This would make it very apparent if a scope permits an operation, without hidden assumptions (almost), which I think is a good thing for authorization. This would also enable a use case that I haven't seen discussed above: a VO having more than one entry-point at a storage endpoint, as discussed in https://github.com/WLCG-AuthZ-WG/common-jwt-profile/pull/45#discussion_r1417355605. However, if I understand correctly, this is exactly the uniform namespace solution, which @chaen says is impractical, right?

On the other hand, I'm not sure I understand the proposal of using the aliases.

  1. when you say that the scope is storage.read:$SCRATCH$/mylfn.root do you mean that that string is literally in the token?
  2. if so and assuming IAM is modified to issue such tokens (I doubt it would be easy and quick), who is the recipient of such a token? Rucio, FTS or the storage?
  3. if it is the storage, I suppose it needs a mapping mechanism similar to what is done now for a path (at least that's how StoRM works). So, why don't just use a path (e.g /lhcb/scratch) instead of an alias?

Depending on the answers, I may have also further doubts about the distribution mechanism of the aliases via the token issuer.

chaen commented 7 months ago
  1. yes, literally
  2. Storage endpoints
  3. Correct, it needs a mapping. And just using a path /lhcb/scratch requires the uniform namespace, which is impossible.

Can you share your concern with having an extra well-known endpoint in the token issuer ? We could also have this well-known hosted somewhere else (DIRAC or Rucio), providing something in the token-issuer redirects to it.

chaen commented 6 months ago

let me bring up that issue again, as the problem is still there :-)