SQS STS Temporary Credentials - amazon-sqs

Is there way to request a temporary token in STS to allow access to only a particular SQS Queue? I'm trying to find a way to restrict access to only ReceiveMessage and DeleteMessage to only a specific queue.

Related

Efficiently authorizing a Client Credentials OAuth2ClientRequest in a multithreaded context with Spring Security 5.2+

With the introduction of OAuth2AuthorizedClientManager in Spring Security 5.2, it's possible to handle the authorization of OAuth2 clients with HTTP clients or abstractions other than WebClient.
We could use something like
OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(
OAuth2AuthorizeRequest
.withClientRegistrationId("registration-id")
.principal("client-id")
.build()
);
Reference: https://github.com/spring-projects/spring-security/issues/8018#issuecomment-601183465
Although I can now get an access token from the OAuth2AuthorizedClient (e.g. String accessToken = authorizedClient.getAccessToken().getTokenValue()), I must always first call authorizedClientManager.authorize(oAuth2AuthorizeRequest) to ensure that I have a valid access token before calling a downstream service. If the access token is expired, the authorize call will perform a Client Credentials call to the token endpoint and get a response back with a fresh token. However, if my microservice receives multiple calls at the same time (e.g. on different request threads), the authorize call could theoretically call the token endpoint for every request thread because each request thread will determine that the access token is expired and request a new one before calling the downstream service. Only once the the OAuth2AuthorizedClientRepository is updated with a valid token, will the request threads stop invoking more token endpoint calls. Also, there may be a flurry of token endpoint responses that will overwrite each other with the final response's access token getting persisted in the the repository until the next expiration.
I'd like to find a way to efficiently authorize client credentials clients in a multithreaded context so that I don't trigger a race condition of token requests. The only ways around this that I can think of is to schedule authorizations before the access token expires or for Spring Security to prevent multiple token endpoint calls if it's waiting for the first response.
Any suggestions would be greatly appreciated.

How should a message queue consumer impersonate a user in Identity Server 3 in a microservices environment?

We have a microservices environment using Identity Server 3. Identity is provided to http microservices via bearer tokens in the authorisation http header, where the token is a JWT. That JWT usually represents a logged in end user, but it can also sometimes represent a system user that has authenticated via client credentials flow.
Messages are published on a queue (RabbitMQ) by these microservices, to be processed asynchronously. Currently, we have a windows service which consumes those messages. It authenticates as a system user with client credentials, and sends that JWT in the auth header to other http microservices.
We would like to maintain the identity of the user that publishes the messages throughout the flow, including within the machine-to-machine (m2m) communication when a message is consumed from the queue and when that consumer calls other microservices. Ie, when Service A (which was provided with a JWT) publishes a message to the queue, then the windows service should be able to impersonate the user represented in Service A's JWT, and should be able to provide a JWT representing that same user when calling Service B.
Service A (running as alice) --> RMQ
RMQ <-- Win Service (running as alice) --> Service B (running as alice)
Only clients with the correct claim should be able to impersonate a user in this way.
Which flow should I use in order to return the JWT to the Windows Service and how should this be achieved in Identity Server 3? I've managed to generate the JWT using Resource Owner flow, passing in a dummy username and password (overriding AuthenticateLocalAsync), although I've not yet attempted to check that the Win Service's client has a valid claim to impersonate. Or should this be a custom flow, implementing ICustomGrantValidator? Perhaps client credentials flow can be used?
Note that the original JWT can be provided with the message, or just the user id itself. The original JWT may have expired, which is why the windows service has to re-authenticate in some way.
My understanding is you want to propagate authenticated identities through a distributed architecture that includes async messaging via RabbitMQ message broker.
When you send/publish messages to RabbitMQ you might consider including the JWT in the message headers i.e. similar to how JWTs are included in HTTP headers for calls to protected HTTP routes. Alternatively if you're feeling a bit lazy, you could just have the JWT directly on the message payload. Your async (Windows service) consumer could validate the JWT on it's way through or it might just pass it through on the subsequent HTTP requests to protected routes of 'other http microservices'.
I'm not sure if you're question about 'which flow should I use' is relevant as presumably the user is already authenticated (via one of the OIDC/authN flows e.g. authentication code grant, implicit, ROPC...) and you're just looking to propagate the JWT through the distributed architecture for authZ purposes...
In terms of sending custom message headers, I have done this with RabbitMQ and MassTransit, but it was for (OpenTracing) trace Id propagation between asynchronous message broker operations. Repo is on GitHub here - might give you some ideas about how to achieve this...
[edit] following clarification below:
Below are some options I can think of - each one comes with some security implications:
Give the async (windows service) consumer the JWT signing key. If
you go down this path it probably makes more sense to use symmetric
signing of JWTs - any service with the symmetric key would be able
to re-create JWTs. You could probably still achieve the same result
with asymmetric signing by sharing the private key, but (IMO) the
private key should be only be known to the authorization server (when using asymmetric signing).
When the user authenticates, request a refresh token by adding
offline_access to the list of scopes specified on the /token
endpoint. You could then pass the refresh token through to the async
(windows service) consumer, which would be able to use the refresh
token to obtain a new access token if the previous one has expired (or just get a new one each time).
There's probably some security considerations that you'd need to
think about before going down this path.
Increase the timeout
duration of the access tokens so that there's enough time for the
async (windows service) consumer to handle the requests. Not sure if
this is viable for your scenario, but would be the easiest option.

Does deleting a Twitter webhook really require me to have all related consumer credentials?

In the Twitter Account Activity API documentation for deleting webhooks, the following authentication requirement is listed:
Requires Authentication Yes (user context - all consumer and access tokens)
Source: https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/aaa-premium#delete-account-activity-all-env-name-webhooks-webhook-id
This would mean that when I build an application that is managing these webhooks using it's own api key and secret, and allowing multiple users to use the webhooks through their consumer key and secret, I am not allowed to shut down my webhooks if for some reason I don't have all the right consumer's access tokens handy.
I can force the webhook to invalidate, because I'm in control of the crc, but that's just awkward. Is it true that I can not, in code or otherwise, delete one of my webhooks if I no longer have any of the consumer credentials used to create it?
The example is also for a single credential, and I'm not sure how I'm supposed to send multiple credentials, especially regarding OAuth1 signing..

Is it possible to re-use access token at multiple server - IdentityServer4

Currently, we are building a web-based application, and we have web-server and we have application server host our resources. Also we will use Mule ESB to be able to use any web-service or api. And we will have Alfresco DMS solution and we will use alfresco service with Mule ESB .
We are investigating how we can implement SSO approach for this scenario. We have already IdentityServer4 for identity federation. It issues access token for client, and we need to authenticate the user whenever the user at the Mule ESB side without asking user the credentials again.
According to my researches, external Identiy provide can be added on Mule ESB. The thing we do not is that can the access token issued the cliet while user logging into application server be passed to Mule ESB and Mule ESB can validate the access token before
Actually, the question that we are looking for answer is that is it possible issue client an access token only for once, then validate this token in each side (Mule ESB, Alfresco) without asking user to enter the credentials again and again.
Using access token for multiple applications is not recommended. This is highlighted through this and this resources. Basically scope of the access token must be restricted. This is to precent access token being misused.
In your scenario, you have multiple applications. If you goal is to use one access token shared across all of them, I suggest not to do that. Instead, you may use single access token against multiple APIs given that you request access tokens with such scope. For example, APIs in ESB can be designed to accept access tokes if scope allowed to do so (scope can be validated from API endpoint through token introspection). But allow each client app to obtain their own tokens. This make your architecture more secure.
One solution for SSO is to allow browser based SSO. Identity providers maintain a session in the browser. So if one of your client go through a login, your next client will use that previous session to skip the login page. This is essentially a SSO behavior. For example this is what allows you to use Gmail, Youtube and Google Drive with single login. Browser maintain a session with Google. Each app obtain tokens, but skipping login page.

Is there a way to restrict AWS Cognito users to only push to own SQS queue?

Consider thousands of users each authenticated by Amazon Cognito.
Each of these users is to have it's own SQS queue. Is it possible to define an IAM role which restricts a user access to only it's own queue?
I'm thinking of somehow using Cognito credentials in combination with IAM variables to define a queuename based on a cognito user-id. Not sure where to start looking though.
To the best of my knowledge, you can't use Cognito to restrict access to a queue named after that identity. The IAM variable for the Cognito identity id is ${cognito-identity.amazonaws.com:sub}, and that will be of the format region:uuid. I believe that colon causes problems in the SQS arn format.

Resources