camaraproject / QualityOnDemand

Repository to describe, develop, document and test the QualityOnDemand API family
https://lf-camaraproject.atlassian.net/wiki/x/XCPe
Apache License 2.0
42 stars 60 forks source link

List endpoint for active sessions of authenticated user #101

Closed mariobodemann closed 3 months ago

mariobodemann commented 1 year ago

Summary

Create a /get endpoint offering a paginated response of all sessions that the currently authenticated user created and are still active.

Context

While testing the APIs it might happen that the session id from a successful create request will get lost. In that case, there is no way to retrieve the created sessions: The /get endpoint only returns sessions whose ids are known, but not all active ones for the authenticated user.

Proposal

Add a variant of the /get endpoint that takes optionally page information to return all sessions for the authenticated user. We optionally need pagination information, since more sessions might be available then we can return (think response size limits etc). Therefore this endpoint must be paginated.

The default values for the paginated parameters current page would be set to 0 and the size of a page to 100. So on average no page information is needed, but for heavy users, it is available.

The sorting of the response could be by it's startedAt field: sessions created early should appear before later sessions.

cURL example

This is an example of the proposed endpoint:

A call like

curl --request GET '{{baseUrl}}/sessions?page=4&pageSize=10' --header 'Authorization: <token>'

would return

{
  "pageSize": 10,
  "pageNumber": 4,
  "sessions": [
    {
      "id": "f0a49ce4-bda0-76eb-879c-3f19db88e985",
      "qos": "QOS_M",
      "ueId": {
         /// ....
      },
      "asId": {
         /// ....
      },
      "duration": 10
      "expiresAt": 1639566000,
      "startedAt": 1639479600,
    },
    /// 9 more sessions
  ]
}

Alternatives

A) One of the main reason for this proposal is the inability to find created sessions. This mostly stems from testing and due to user error the session id cannot be retrieved from the initial create request. In order to not block the ue and only create the needed amount of sessions, the default of the duration parameter could be set to a very low value: a 10 seconds duration would be deleting the session after 10 seconds, without the need to delete a session without the session id.

B) A second alternative could be to add a delete all endpoint: With this endpoint, we would not give out the session information, but could guarantee in an error case, there is the ability to delete existing sessions.

Initial Specification Proposal

Under #100 you can find an initial draft of a proposal on how the specification would need to change. (closed now, till a decisions on this issue is found)

jlurien commented 1 year ago

It is true that without the session id it is not possible to get info about or delete a session, and there is no way currently to discover it, so an GET /sessions endpoint would make sense.

With client_credentials, a client may have many sessions and in that case pagination would make sense, or alternative some support for filtering (for example based on ueId), or both. There are some guidelines proposed, but they may require some refinement as I think no CAMARA API has added these type of parameters yet.

If the main driver is to delete sessions without knowing the session id, another possibility is to allow a DELETE /sessions with filtering support to delete only a subset of sessions for that client, for example by ueId.

mariobodemann commented 1 year ago

Thank you for the feedback.

I think it is a great idea to refine the suggestion to use the pagination parameters as specified by the guidelines, but I am not sure if those guidelines are finalized and ready to go, or if they are still in development.

For me the main driver would be to be able to determine which sessions are currently running, with the side effect of being able to delete them. This means that a delete-all endpoint feels more like a stop gap solution then a real one.

jlurien commented 1 year ago

A GET /sessions endpoint makes all sense to me. We can elaborate on the paging and/or filtering parameters. Guidelines are a start point but probably the first API needing them will lead the way.

This new endpoint add new requirements on implementations as sessions have to be associated to an owner in order to only provide "their" sessions, that is the 2-legged client_id or 3-legged user_id. So far the concept of ownership is not mentioned explicitly, and relying on the knowledge of a non guessable session_id could have served for short term. But for this new endpoint I think we should address it.

hdamker commented 1 year ago

Due to the requirements this new endpoint would imply for implementations we propose to move the proposal into the backlog. Also as this endpoint would be only relevant in dev/lab/test ... the main issue can be circumvented with setting a (short) duration for the QoS session.

mariobodemann commented 1 year ago

Thanks for the update.

Would implementing the alternative A be an option as a compromise?

https://github.com/dt-developers/QualityOnDemand/blob/9f34da6fef175bf774bb9ea7d835707b36255906/code/API_definitions/qod-api.yaml#L303

hdamker commented 1 year ago

Would implementing the alternative A be an option as a compromise?

My view: Setting the default value for duration to a low value can e.g. be done locally in lab/test environments. And developers can always set it in their session create calls if they like. If we set it in general to a low value we are essentially make the parameter mandatory, at least before we have a /put or /patch method (#47). Therefore I'm not in favor of a short default duration to circumvent these issue in dev/test/lab.

But open for other thoughts on it.

jlurien commented 1 year ago

Hi, I have received recently some internal feedback to work on this functionality, to allow customers to "look for" active sessions in scenarios where sessionId is not known. I think that this functionality makes all sense in a CRUD model, but as mention before we must elaborate well the requirements around which sessions are allowed to be discovered by certain client, which filters may apply to that query, e.g. searching for sessions for certain MSISDN, etc.

TEF can work on a more detailed proposal for this

RandyLevensalor commented 1 year ago

Could we add parameters to filter this to include different session status? Do we have a list of session statuses? Active, completed, failed?

eric-murray commented 1 year ago

I don't think a GET /sessions that returns the details of all sessions works. Those details include personal information for each device (e.g. phoneNumber), so how would this work for three-legged authentication? Are you proposing the API consumer puts the full list of device identifiers they are managing sessions for in the login_hint? That could be a very long list, would take a very long time to process, and may well exceed maximum URL length.

We already have a GET /sessions/{sessionId}, so all we need is a GET /sessions that return the list of sessionIds, and nothing else. No personal information there. Each session can then be queried individually using GET /sessions/{sessionId} until you find the one you want.

I thought that was the RESTful way to do it anyway.

jlurien commented 1 year ago

What @eric-murray mentions is something we have to define properly. In any case, the requester must have access rights to the requested information. That means that the access token must be checked in order to identify which specific sessions are associated to it. Even if we only returned sessionIds, we cannot return those corresponding to sessions not created by the requester.

In case of three-legged authentication the check must include also that sessions belong to the user identified by the token. So functionality must always be: "Get me the sessions I'm allowed to discover with this access token".

eric-murray commented 1 year ago

That means that the access token must be checked in order to identify which specific sessions are associated to it. Even if we only returned sessionIds, we cannot return those corresponding to sessions not created by the requester.

I'm concerned that you are saying all that matters for this use case is which API consumer (identified by client_id for both 2- and 3-legged tokens) created the sessions and not the consent of the end user (identified by sub in the associated id_token for a 3-legged token but not identified at all for a 2-legged token) whose personal information may be in the session information.

Whatever logic is used to implement the GET /sessions endpoint, it must only return sessions created by the client identified by the token, and that could be either a 2- or 3-legged token for this purpose. But are you saying that, if a session already exists, then end user consent does not need to be re-checked even if user resource (in this case, the device fields) is involved? The API consumer cannot consent to this, because this personal information is not theirs.

If that is the case, a 2-legged token is then fine for session retrieval and the Identity & Consent technical ruleset is wrong. But if 3-legged authorisation is required, what does the API consumer (client_id) specify as the login_hint to allow consent checking to be completed during the /bc-authorize step?

jlurien commented 1 year ago

I'm not meaning at all that client_id is the only part of the access token to be checked. For sure, consent has to be checked for 3-legged scenarios which require it. The consent would be check before an access token with scope qod-session-read is granted for the client and the user.

My point was that returning only sessionId, if we have an endpoint to get the additional details from that sessionId, does not change the situation regarding privacy.

SyeddR commented 1 year ago

@jlurien How do you handle a situation where a client have created 100s or more sessions? Would you list them all in one GET /sessions? This could make an endpoint susceptible to heavy read request, or possible denial of service attack if not implemented correctly.

jlurien commented 1 year ago

@jlurien How do you handle a situation where a client have created 100s or more sessions? Would you list them all in one GET /sessions? This could make an endpoint susceptible to heavy read request, or possible denial of service attack if not implemented correctly.

This is related to which type of token we use. I agree that with 2-legged tokens, a client_id may own hundreds of sessions. An alternative to paging would be to add filters by device, but I'm not against considering paging for these scenarios.

For 3-legged tokens. it may not be that necessary as an individual user will likely not have hundreds of sessions.

The ultimate question is which kind of tokens are we going to use here. This is connected to the ongoing discussions in Identity and Consent Management WG. The general guideline is that "Every time personal user data is processed by an API and the user can exercise their rights either via opt-in and/or opt-out, 3-legged access tokens must be used.".

For the API definition, we could consider paging in any case, as it is optional, but it is more important to define the rules about which sessions are to be returned.

hdamker commented 1 year ago

From the discussions on the QoD Call on Friday:

The PR is stil (optional) considered for v0.10.0. Potentially the discussions can be not be closed for v0.10.0, in this case the feature will be postponed to the next release.

Discussions which are open:

  1. Can the endpoint deliver (A) all sessions created by the requesting API consumer or (B) only the ones for the user resource within the (3-legged) token? (in other word: does the endpoint later require 2-legged or 3-legged token, in case 3-legged token will (later) be required to create a QoD session resource)

    • For now the assumption is that the operation delivers all sessions which are authorized by the token (all sessions created for 2-legged, only user sessions for 3-legged). Decision about needed token is postponed.
  2. Should the operation deliver the full session information or just the session ids?

    • Result of the discussion: return the full session information
    • Rational: this is the more developer friendly option, as otherwise the API consumer would need to call getSession one by one to find the information they are looking for. From privacy perspective has the API consumer provided and seen all personal information already during the respective session creations. It should be enough that the API consumer was authorized to create the sessionId(s) to assume consent for the get operation.
  3. Is paging needed or not?

    • That depends on the answer to point 1. If only the sessions for one user device are delivered is no paging necessary. If all sessions for an API consumer are delivered then paging might be needed to avoid excessive data within the response
  4. Filtering by device or phoneNumber (Added after the call, comment from Randy https://github.com/camaraproject/QualityOnDemand/pull/228#discussion_r1397522143)

    • Is it possible to filter with a complex object?

@RandyLevensalor @jlurien @eric-murray ... please add your thoughts on the points.

patrice-conil commented 1 year ago

From the discussions on the QoD Call on Friday:

The PR is stil (optional) considered for v0.10.0. Potentially the discussions can be not be closed for v0.10.0, in this case the feature will be postponed to the next release.

Discussions which are open:

  1. Can the endpoint deliver (A) all sessions created by the requesting API consumer or (B) only the ones for the user resource within the (3-legged) token? (in other word: does the endpoint later require 2-legged or 3-legged token, in case 3-legged token will (later) be required to create a QoD session resource)

    • For now the assumption is that the operation delivers all sessions which are authorized by the token (all sessions created for 2-legged, only user sessions for 3-legged). Decision about needed token is postponed. Totally agree on all sessions created for 2-legged, only user sessions for 3-legged
  2. Should the operation deliver the full session information or just the session ids?

    • Result of the discussion: return the full session information
    • Rational: this is the more developer friendly option, as otherwise the API consumer would need to call getSession one by one to find the information they are looking for. From privacy perspective has the API consumer provided and seen all personal information already during the respective session creations. It should be enough that the API consumer was authorized to create the sessionId(s) to assume consent for the get operation. I prefer "Return the full session information" that is more user friendly
  3. Is paging needed or not?

    • That depends on the answer to point 1. If only the sessions for one user device are delivered is no paging necessary. If all sessions for an API consumer are delivered then paging might be needed to avoid excessive data within the response No need to paginate for "single device" in 3 legs, so if we plan to migrate to 3 legs, no need to paginate at all
  4. Filtering by device or phoneNumber (Added after the call, comment from Randy Add GET /sessions endpoint for retrieving all active sessions of authenticated user #228 (comment))

    • Is it possible to filter with a complex object? I will prefer to define ipv4Address, ipv6Address,... as filter criteria, because is more simple.

@RandyLevensalor @jlurien @eric-murray ... please add your thoughts on the points.

hdamker commented 1 year ago

Thanks @patrice-conil for your comments on the four points ... I agree with all of them.

@RandyLevensalor @jlurien @eric-murray I would like to get your opinion if we can go today with the PR #228 as is, which means:

  1. Change of security schema will not impact the endpoint definition, as it will implicitly will deliver only the sessions allowed by the token
  2. Returning full session information as agreed
  3. No pagination for now as it don't seem to be necessary
  4. Only phoneNumber as filter parameter. It is possible to add further filter parameters in next version, that's no breaking change. But ipv4address would need some discussion, as not enough to identify a device.

Let me know if a) you would merge the PR as is into v0.10.0 or b) see the need to continue the discussion first and postpone the PR to next release

If there are no approvals for the PR until end of day, I'm going for b) to get the rc v0.10.0 done.

RandyLevensalor commented 1 year ago

Only phoneNumber as filter parameter. It is possible to add further filter parameters in next version, that's no breaking change. But ipv4address would need some discussion, as not enough to identify a device.

I'm not a fan to only support mobile networks. Especially when we have discussed wireline networks supporting more concurrent sessions. Why can't we we search on for a match on the device schema that's used to create the session and further refine it in a larger pr, if needed?

hdamker commented 1 year ago

@RandyLevensalor

Why can't we we search on for a match on the device schema that's used to create the session and further refine it in a larger pr, if needed?

We couldn't simply filter by whole device object - it would require changing the method from GET to POST and delivering the request body as a device object parameters to filter. Instead I'm here with @jlurien:

Is it possible to filter with a complex object?

I will prefer to define ipv4Address, ipv6Address,... as filter criteria, because is more simple.

And that can be done step by step in later releases, in line with any redefinition of device which will come.

jlurien commented 1 year ago

Only phoneNumber as filter parameter. It is possible to add further filter parameters in next version, that's no breaking change. But ipv4address would need some discussion, as not enough to identify a device.

I'm not a fan to only support mobile networks. Especially when we have discussed wireline networks supporting more concurrent sessions. Why can't we we search on for a match on the device schema that's used to create the session and further refine it in a larger pr, if needed?

This is something that we should clarify at WG level, The scope of the subproject as stated in the README says:

It provides the customer with the ability to: set quality for a mobile connection (e.g. required latency, jitter, bit rate) get notification if network cannot fulfill NOTE: The scope of this API family should be limited (at least at a first stage) to 4G and 5G.

There is also another subproject dedicated to Home Devices QoD, which target home networks.

eric-murray commented 1 year ago

From the API Design Guidelines:

In such cases, it is recommended to use one of the following methods to transfer the sensitive data:

  • When using GET, transfer the data using headers, which are not routinely logged or cached
  • Use POST instead of GET, with the sensitive data being embedded in the request body which, again, is not routinely logged or cached

So MSISDN should not be passed as a query parameter, and certainly that is not allowed by Vodafone's own API security rules.

Filtering by MSISDN (or, indeed, any device identifier) needs to be achieved using a 3-legged access token. Indeed, the CAMARA APIs Access and User Consent Management Guidelines say that a 3-legged access token should ALWAYS be used for such endpoints, though I agree this is unworkable when the API is processing personal data for multiple end users.

So the phoneNumber query parameter needs to be removed before I can approve this.

On the other points:

jlurien commented 1 year ago

From the API Design Guidelines:

In such cases, it is recommended to use one of the following methods to transfer the sensitive data:

  • When using GET, transfer the data using headers, which are not routinely logged or cached
  • Use POST instead of GET, with the sensitive data being embedded in the request body which, again, is not routinely logged or cached

So MSISDN should not be passed as a query parameter, and certainly that is not allowed by Vodafone's own API security rules.

Filtering by MSISDN (or, indeed, any device identifier) needs to be achieved using a 3-legged access token. Indeed, the CAMARA APIs Access and User Consent Management Guidelines say that a 3-legged access token should ALWAYS be used for such endpoints, though I agree this is unworkable when the API is processing personal data for multiple end users.

So the phoneNumber query parameter needs to be removed before I can approve this.

On the other points:

  • I don't think this endpoint can be called using a 2-legged token (given the current user consent guidelines), but this has no effect on the YAML, so we can park that discussion for now
  • I still don't understand the argument that calling GET /sessions/{sessionId} multiple times to get the session details is more effort for the API developer, as these APIs will all be called programmatically. Who is expecting to be sat in front of a terminal typing these API calls? But if the consensus view is that all session details are returned, then I can agree to that because it just means that the API implementor has to call GET /sessions/{sessionId} multiple times instead (even if I still don't understand how you can get details for multiple end users with a 3-legged token).
  • Paging (and indeed filtering) greatly increases implementation complexity, so my preference is also not to define paging or filtering at this stage

I agree with your points. However, for GET /sessions I still think that returning the list of sessions with all data is more useful than returning just the list of Ids. Probably, in a 3-legged scenario it will be typical to have just one session.

In summary, if we go for complex filters, I would suggest a POST operation to list or search for sessions, returning a list of matched sessions info.

RandyLevensalor commented 1 year ago

Only phoneNumber as filter parameter. It is possible to add further filter parameters in next version, that's no breaking change. But ipv4address would need some discussion, as not enough to identify a device.

I'm not a fan to only support mobile networks. Especially when we have discussed wireline networks supporting more concurrent sessions. Why can't we we search on for a match on the device schema that's used to create the session and further refine it in a larger pr, if needed?

This is something that we should clarify at WG level, The scope of the subproject as stated in the README says:

It provides the customer with the ability to: set quality for a mobile connection (e.g. required latency, jitter, bit rate) get notification if network cannot fulfill NOTE: The scope of this API family should be limited (at least at a first stage) to 4G and 5G.

@jlurien We should fix this. This is the first time that I've seen any pushback in any working group to supping wireline networks.

This was added to commonalities to avoid being telco specific. https://github.com/camaraproject/Commonalities/blob/main/documentation/API-design-guidelines.md#25-reduce-telco-specific-terminology-in-api-definitions

There is also another subproject dedicated to Home Devices QoD, which target home networks.

But this can be a home network behind a FWA network and I think that is where most of the use cases are coming from, not home devices connected to wireline network.

patrice-conil commented 10 months ago
* I still don't understand the argument that calling `GET /sessions/{sessionId}` multiple times to get the session details is more effort for the API developer, as these APIs will all be called programmatically. Who is expecting to be sat in front of a terminal typing these API calls? But if the consensus view is that all session details are returned, then I can agree to that because it just means that the API implementor has to call `GET /sessions/{sessionId}` multiple times instead (even if I still don't understand how you can get details for multiple end users with a 3-legged token).

If you have to call GET /sessions/{sessionId} multiple times, you have to call them in parallel otherwise you will multiply response times... and believe me, it's not always easy... much more complex than reading a list, especially to handle errors/timeouts

eric-murray commented 10 months ago

@patrice-conil And how long do you think it will take to get a 3-legged token valid for all possible end users whose session details might be returned by GET /sessions? The response list will include a device identifier (i.e. end user identifier) for each entry, and according to CAMARA-API-access-and-user-consent.md:

[Client credentials] can only be used when no personal user data is processed

So 3-legged token it is.

patrice-conil commented 10 months ago

Hi @eric-murray, On my side, the session belongs to the client_id who created it... and will only be returned to this client_id. This is how I solved the isolation issue...whether I am called by GET /sessions or GET /sessions/{sessionId} I will check if the session was created by the caller. My comment only concerns the complexity of one request versus multiple requests. And in fact if you get a 3-legged token valid for all users... you can call GET /sessions/{sessionId} as many times as necessary to retrieve the same information, right? Of course, in all cases, to manage personal data, I prefer a 3-legged one.

eric-murray commented 10 months ago

@patrice-conil

On my side, the session belongs to the client_id who created it... and will only be returned to this client_id.

Yes, I agree, but the session information still contains personal data (IP address or phone number), and returning those details is "processing". So the token still needs to be associated with all the end users for which the API consumer has active sessions. That may just be one, or it may be many, or it may be very very many.

Thing is, when the session is created, the API consumer will have a 3-legged token valid for the resulting sessionId (this assumes that a wild card scope has been requested). So they will not need another token to call the GET /sessions/{sessionId} endpoint - the one they have is fine so long as they remember which sessionId it is associated with.

But if they need a 3-legged token valid for multiple end users, well, they need to request that specifically.

Ignoring the complexity of getting a valid token for now, if the list is long, then it will need to be paginated. So that will increase complexity whereas the GET /sessions/{sessionId} response will not need to be paginated.

So my feeling is that, if one single list of session details is required, then we should mandate filtering by end user identifier. That way, we get a shorter list, and can use a "normal" 3-legged token for that end user, which the API consumer will already have. This could still be GET /sessions, but with the end user identified from the token. Should such a thing as "multi-user" 3-legged tokens exist, these should be rejected.

But my preference remains that GET /sessions returns only a list of sessionIds. Client credentials can be used for that endpoint.

patrice-conil commented 10 months ago

@patrice-conil

On my side, the session belongs to the client_id who created it... and will only be returned to this client_id.

Yes, I agree, but the session information still contains personal data (IP address or phone number), and returning those details is "processing". So the token still needs to be associated with all the end users for which the API consumer has active sessions. That may just be one, or it may be many, or it may be very very many.

These personal data are already known to the client_id who provided them when creating the session... so no problem for me. The real difficulty is returning only valid data for the token used to create sessions (the same one used in your approach to call GET /sessions/{sessionId}. Filtering by end user is therefore implicit in case of 3 legs, because the end user is involved in obtaining the token. WDYT?

Thing is, when the session is created, the API consumer will have a 3-legged token valid for the resulting sessionId (this assumes that a wild card scope has been requested). So they will not need another token to call the GET /sessions/{sessionId} endpoint - the one they have is fine so long as they remember which sessionId it is associated with.

But if they need a 3-legged token valid for multiple end users, well, they need to request that specifically.

It's not my idea ... they will use the same token for create and list operations.

Ignoring the complexity of getting a valid token for now, if the list is long, then it will need to be paginated. So that will increase complexity whereas the GET /sessions/{sessionId} response will not need to be paginated.

So my feeling is that, if one single list of session details is required, then we should mandate filtering by end user identifier. That way, we get a shorter list, and can use a "normal" 3-legged token for that end user, which the API consumer will already have. This could still be GET /sessions, but with the end user identified from the token. Should such a thing as "multi-user" 3-legged tokens exist, these should be rejected.

Totally agree with you.

But my preference remains that GET /sessions returns only a list of sessionIds. Client credentials can be used for that endpoint. In this case, won't the consumer have to use 2 different security schemes to call POST /sessions and GET /sessions ?

eric-murray commented 10 months ago

... they will use the same token for create and list operations.

OK, I can live with that. A GET /sessions endpoint that returns full session details, but can only be accessed using a token that was already used for POST /sessions (so only associated with a single end user). In that way, the GET /sessions list would only be for the end user associated with the token.

In this case, won't the consumer have to use 2 different security schemes to call POST /sessions and GET /sessions ?

Both could be used. 2-legged token for GET /sessions would return a list of all sessionIds created by the API consumer. 3-legged token would filter that list to only those for the end user associated with the token (but still only return list of sessionIds). Implementation complexity would increase, of course.

jlurien commented 10 months ago

This is long thread but summarizing the open points, I think we should decide on:

Filtering

Taking into account that we should avoid disclosing sensible data in paths and query parameters, I think we should choose a POST method for this operation, so it would be POST /sessions/retrieve. This gives us a lot of flexibility designing the filters in the request body, and we can reuse the same schemas that we use in other operations. The most obvious input parameter is probably the device, but we may decide to add other properties of the SessionInfo model, such as appicationServer,qosPropfile`...

We have to device if device is always required, or some minProperties are required, or even if an empty body would be allowed indicating no filters.

security & securitySchemes for the operation

Designing the operation as a POST simplifies a lot this point, as this new operation would be conceptually similar to the operation for session creation regarding security. Same considerations should apply to both. A client allowed to create a session for certain device should be allowed as well to retrieve the session info for that device. In 3-legged tokens are required for that, same token would be required to get the session data.

In case that we allow a retrieveSession operation without filters, we should rely only on the access token content to decide which sessions are authorized by the access token. In case of 3-legged tokens, this implies looking into the sub identifying the user and likely into any other identifiers for the specific device or subscription of the user.

response body

Here I would return an array of SessionInfo, again similar to the createSession operation but allowing several items to be returned, as a device may have several sessions.

I think paging will not be necessary for 3-legged scenarios.

Draft proposal

So in summary, I would propose an operation that could be drafted as:

paths:
  /sessions/retrieve:
    post:
      description: Retrieves session(s) that match the input in the body. 
      operationId: retrieveSessions
      requestBody:
        content:
          application/json:
            $ref; "#/components/schemas/RetrieveSessions"
      responses:
        "200":
          content:
           application/json:
              schema:
                type: array
              items:
                $ref: "#/components/schemas/SessionInfo"
      security:
        - oAuth2ClientCredentials: []
        - threeLegged:
            - "qod-sessions-read"
eric-murray commented 10 months ago

@jlurien

I don't think a POST is necessary in this case because:

Regarding identifying the device from the OAuth token:

Filtering by parameters other than device, devicePorts or applicationServerPorts is straightforward using query parameters, e.g.: GET /sessions?applicationServer.ipv6Address=2001:db8:85a3:8d3:1319:8a2e:370:7344

As the list must be filtered by end user (i.e. device), and hence will be short, I don't see the need for pagination.

jlurien commented 10 months ago

@eric-murray

To me the decision for GET vs POST is the result of deciding on the filters to apply for the method. I agree with you that without device there a GET is a valid option. My proposal was for the sake of coherence with the other operations we have right now, particularly createSession. So the real debate for evolution would be whether device has to be an input (required, optional or non-existent) for some operation or we should rely always on the device identified by the token.

hdamker commented 10 months ago

@eric-murray @jlurien The agreed text within CAMARA-API-access-and-user-consent.md which we will have to include also in our API specification (after it is released):

CAMARA guidelines defines a set of authorization flows which can grant API clients access to the API functionality, as outlined in the document CAMARA-API-access-and-user-consent.md. Which specific authorization flows are to be used will be determined during onboarding process, happening between the API Client and the Telco Operator exposing the API, taking into account the declared purpose for accessing the API, while also being subject to the prevailing legal framework dictated by local legislation.

It is important to remark that in cases where personal user data is processed by the API, and users can exercise their rights through mechanisms such as opt-in and/or opt-out, the use of 3-legged access tokens becomes mandatory. This measure ensures that the API remains in strict compliance with user privacy preferences and regulatory obligations, upholding the principles of transparency and user-centric data control.

That does not exclude that the QoD API can be used with Client Credentials. Even if most local legislations would require 3-legged for all purposes, there would be still deployment scenarios where the QoD API will be used with Client Credentials (e.g. in lab deployments or private networks). Therefore we can't get completely rid of the device parameter but should keep it at least optional.

But as @jlurien rightly recognized, that is going beyond this issue.

jlurien commented 10 months ago

With @hdamker remarks, I tend to think that probably the most safe approach is to consider device as an optional input parameter for both retrieveSessions and createSession, in which case I would model both in a similar way with a POST method.

Apart from the hypothetical 2-legged possibility in some environment or geography, there is also a possible 3-legged scenario where a token is granted for a user (sub) which may have several lines, for example using user/pass credentials, and in that case it may be necessary to indicate which of the user devices is requested.

eric-murray commented 10 months ago

@jlurien @hdamker I agree that if we want to keep device as an optional input parameter, then we need to use POST. I'd also add a comment that this field will be ignored if a device can be identified from the token so that the behaviour is clear.

I'm not convinced that multi-user tokens are feasible - it already takes too long to generate and process a token for one end user. But that is indeed not a topic for this issue.

jlurien commented 8 months ago

To propose a PR we should have some prior consensus on how to model the endpoint. The options I see:

a) GET /sessions -> No explicit input parameters. All input has to be taken from the access token

b) POST /sessions/retrieve { device required } -> Similar behaviour of current createSessions

c) POST /sessions/retrieve { device optional } -> If device is included, similar behaviour of current createSessions. If device is not included, all input has to be taken from the access token.

The implications can be extended to the current endpoints. There are some questions that are not yet resolved:

jlurien commented 6 months ago

To proceed with this functionality, which is in the backlog for v0.11, I propose to align the new endpoint as much as possible to the current consensus in v0.10.

That would imply modelling the endpoint as option B above (POST /sessions/retrieve { device required } ). In parallel, there is an ongoing discussion in https://github.com/camaraproject/Commonalities/issues/171 to consider the input device as optional, and rely on the access token when is possible (which would be the option C above). If there is a final decision in Commonalities to make device optional, then we would have to align both the current createSession and the new retrieveSessions.

If this is OK, I can model a PR with the proposal.

RandyLevensalor commented 6 months ago

My concern is that I don't see anything that would limit the three-legged token to just on device, but a set of devices. While I can see expanding this to retrieve all sessions associated within the scope of the token, I think that we'll still need to support the device id. Added this comment to the commonalities issue as well. https://github.com/camaraproject/Commonalities/issues/171#issuecomment-2141148578

For the device ID, what about embedding the json from the #/components/schemas/Device schema in the requestbody. Then if we need to update the Device schema to comply with commonalities, we'll only have to do it in the QoD schema.

jlurien commented 6 months ago

The debate is in Commonalities, but there are many cases where a 3-legged token will identify a single device, such as in a network-based auth flow launched from the device. In any case, this will not be a universal case and device has to be supported anyway, optional or required.

The proposal is exactly that, to reuse the same device schema in the request body, modeling an operation POST /sessions/retrieve { device }

jlurien commented 5 months ago

In the PR #299 there is a proposal for an equivalent operation: retrieveProvisions, which could be adapted to the quality-on-demand API

RandyLevensalor commented 5 months ago

Should / could we add a limitation to this endpoint the the 3-legged token would be limited to a single device?

I could see an enterprise customer having a single token to manage QoD on all of their devices. Otherwise enterprise users would have to manage separate token for each device under the same account.

If we go with the limitation in the API or add error handling for multiple devices, then the three legged solution would work.

jlurien commented 5 months ago

Should / could we add a limitation to this endpoint the the 3-legged token would be limited to a single device?

I could see an enterprise customer having a single token to manage QoD on all of their devices. Otherwise enterprise users would have to manage separate token for each device under the same account.

If we go with the limitation in the API or add error handling for multiple devices, then the three legged solution would work.

I understand your question is in the context of making device optional, right?

Depending on the authentication scenario it may be possible that an access token grants management of several devices. e.g. using user/password credentials for a user with several devices. In those cases, an operation like "retrieveSessions" may return all sessions associated to any of the devices associated to the token. We could add a limitation to the operation deciding that only one device is allowed as input, but it's debatible if we should do that.

So the 3-legged solution would work for the retrieveSessions operation, which is able to return an array of SessionInfo, as long as at least one device can be determined from the access token. It wouldn't work for a a createSession operation that is only able to create a session for a single device, if none or more than one devices are associated to the access token.

In the PR for QoD provision API I opted to make device required, as in quality-on-demand APIS, to skip by now the decision about the device being optional.

jlurien commented 4 months ago

As agreed on last meeting, I will propose a PR with the operation modeled with POST. I have not make device optional in the request body yet, as I think it is better to align this new endpoint with all others in the same way (wording, etc), once we create a PR for issue #313. fyi @hdamker

hdamker commented 4 months ago

@jlurien Just seen this discussion and your last comment now. I agree, let's get your PR #325 merged first and then align the optional device across the operation. I started a draft PR for #313 within #326 but not sure that I hit the nail.