Is there a way to get the resource requester value in the resource object in Kubernetes? - authentication

I have a case where we use custom Authorization in Kubernetes via a webhook. Once authorized is there any way the user id could propagated on to the metadata or labels or env of a resource in Kubernetes.
Eg - When a user creates a pod, the userid should be available on the request object.
The only place where the user data is available is in the events that is available via audit logs.

You could use a mutating webhook to inject it. The webhook admission request struct has the user identity data and you can patch the incoming object in the admission response. There is nothing off the shelf for that though, you would have to build it yourself.

Related

API gateway and app backend authentication

I have application with backend and frontend. We are using JWT token for the authentication and Authorization(A2). Now we are planning to use express-gateway as an API gateway (AG) so that backend can be unload from routing and other protection heavy load and shift that burden to AG. Now since we are using AG shall we remove the A2 logic from backend and whatever request comes to backend (every request will be routed from consumer to backend via AG) we treat it as authenticated user and process the request, no need to verify again. If yes then we will still need JWT token to get the payload to extract the information like email id, role etc. For that should we pass the token from AG to backend. Also backed might have different kind of things on payload than EG. How to tackle that.
To pass authentication information on to a server, you need to use the request-transformer policy to add the information to the request headers going to the server, e.g. the following fragment adds a header named eg-consumers-firstname:
- request-transformer:
- condition:
name: authenticated
action:
headers:
add:
jscode: 'req.headers["eg-consumer-firstname"] = consumer.firstname'
The JS variables you can use in jscode sections is not particularly well documented, but you have access to everything in models/users.js.
In general, you can often adjust the gateway.config.yml such that scopes restrict which apiEndpoints (paths) are available to a given user; this is a better way to prevent unauthorized access then doing the processing on the downstream server side, which should do an independent check in case the API gateway has been compromised.

Keycloak uma-grant type tickets for service accounts do not seem to work with policies

I am trying to use the Keycloak AuthzClient to register resources and related permissions in a resource server.
I have a resource server "resourceserver" with authz service enabled.
Using the AuthzClient, initialized with the json file containing the resource server's client id and secret, I'm able to obtain a pat.
...
authzClient.obtainAccessToken().getToken();
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("myresource");
resource.setUris(new HashSet<>(Collections.singletonList("urn:resourceserver:resourcetype1:myresource")));
resource.setOwnerManagedAccess(true);
resource.setType("urn:resourceserver:resourcetype1");
resource.addScope("read", "write");
resource = authzClient.protection(pat).resource().create(resource);
UmaPermissionRepresentation permissionRepresentation = new UmaPermissionRepresentation();
permissionRepresentation.setName("myresourcepermissions");
permissionRepresentation.setDescription("foo");
permissionRepresentation.addRole("somerole");
UmaPermissionRepresentation result = authzClient.protection(pat).policy(resource.getId()).create(permissionRepresentation)
After executing this code, I can see, in the keycloak admin UI, that the resource has been created, and the scopes, however the policy/permission don't seem to show up.
I believe it is probably intended, as this keycloak admin UI only shows policies of types client, role, js, etc., but not "uma" which is what UmaPermissionRepresentation creates.
I can however see that policy exists in Keycloak by querying authz/protection/uma-policy with my pat.
So there is something there. Now testing it. I created a regular user and assigned it the realm role somerole. Using this user and some arbitrary public client, I'm able to get an RPT.
First getting an access token using the password grant:
grant_type=password&username=joe&password=password&client_id=somepublicclient
Then exchanging that for an RPT:
grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&audience=resourceserver
The RPT comes back and if I view its contents, I can see the authorization block giving me access to the myresource resource.
However, when I try a similar flow with a service account (to which I also granted the somerole role)using the client credentials flow to obtain the initial access token:
grant_type=client_credentials&client_id=serviceaccount1&client_secret=77c1ffa8-0ea8-420c-ad45-e1a69a03838d
I am able to obtain an RPT, but that RPT does not contain myresource in the authorization/permission block, only the Default resource.
I have been trying to understand why that is. I have also tried using the .addClient("serviceaccount1") or even .addUser("service-account-serviceaccount1") in the UmaPermissionRepresentation, but still, the policy doesn't seem to kick in and my service account does not have access to the resource.
This is using Keycloak 4.8.0.Final.
Note: using the keycloak admin client, I am able to create policies/permissions that actually make this work; but in my environment this would causes other problems because of the roles I would need to assign to the admin client (like viewing all clients to retrieve an id etc.)
I have the same problem with KeyCloak 11.0.2.
Shared resources do not end up in the permission tickets of service accounts. Service accounts are explicitly excluded in the authorization token service.
Since sharing resources with service accounts is possible, this seems inconsistent.
However, you can work around this by explicitly setting the azp claim to something other than your client_id via a protocol mapper on your client.
.

Express Session not working with DialogFlow

I have deployed an Express app on Heroku, set my web hook on the address and use my DG agent to make post request to the endpoint on Heroku.
The webhook passes over parameters's body to another web service and that's fine. I need to keep track of the cookie the web service passes back in order to send it back to keep the context of the conversation.
At the moment I am saving a file on the server with the Express's session id (req.session.id) and the cookie value. Everything works if I make POST call via Postman or via form, so let's say the web application is tracking sessions properly.
On the contrary, if I test my webhook with the DialogFlow agent, I receive a new session id per each request to my endpoint on Heroku.
I don't understand why... What am i missing?
I do not believe you can rely on the request from DialogFlow maintaining a cookie for you.
We are using DialogFlow, Google Actions, and Node.js. We retain session information by including data in the response we send back, which we then read when the next request comes in. When writing a response we put our session data (JSON) on the assistant.data attribute. When receiving a request we get session data from the incoming event.body.
We had considered trying to live off a unique ID of the incoming request, such as a user ID or device ID, but did not pursue it.

Amazon sns mobile push CreatePlatformEndpoint creates multiple endpoints with same token and user data

I am using amazon sns mobile push for sending push notifications.For registering the device token with amazon I am using the CreatePlatformEndpoint.
As per amazon documentation(http://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) :
The CreatePlatformEndpoint action is idempotent, so if the requester already owns an endpoint with the same device token and attributes, that endpoint's ARN is returned without creating a new endpoint.
But when I use the CreatePlatformEndpoint I am able to register the same token with the same attributes(User data) multiple times(upto 3 times). Not able to understand this behaviour.
chetna bhandari,
I was having this problem. I have a platform application for iOS (APNS) and another one for Android (GCM). For iOS, the method createPlatformEndpoint works fine. But for Android, creates multiples endpoints (up to 3, just like you) with same token. Next time I tried to use createPlatformEndpoint, throws an exception.
The correct way to do this is storing the endpoint in your application. If it's not stored yet, create and store.
Then, the pseudo-code is:
retrieve the latest device token from the mobile operating system
if (the platform endpoint ARN is not stored)
# this is a first-time registration
call create platform endpoint
store the returned platform endpoint ARN
endif
call get endpoint attributes on the platform endpoint ARN
if (while getting the attributes a not-found exception is thrown)
# the platform endpoint was deleted
call create platform endpoint with the latest device token
store the returned platform endpoint ARN
else
if (the device token in the endpoint does not match the latest one) or
(get endpoint attributes shows the endpoint as disabled)
call set endpoint attributes to set the latest device token and then
enable the platform endpoint
endif
endif
You can see in this link:
Create a Platform Endpoint and Manage Device Tokens

Is AEM authentication Stateless

Is AEM Authentication (closed user group) stateless ? What happens if we have multiple publisher, will the authentication handler ensure the user is authenticated in all the instance of the publisher ?
Could not find a document confirming this, So any help is appreciated.
Thanks.
The default AEM Authentication (CRX Login Module) is not stateless , the authentication is confirmed by a login token. When a user logs in the token information is stored under .tokens node of the corresponding user node (/home/users). The value of the token is also stored in the browser as a cookie login-token. Whenever a request comes in , the cookie value and the token in the repository is compared.[
You can test by deleting the .tokens node and refreshing some page that cannot be accessed by anonymous
]
In a multi publisher environment the token is created only on the instance which logged the user in. Since other instances cannot find the token for the cookie value in their repositories the request will be rejected.
If you enable sticky sessions , all requests by a particular client are always directed to the same instance.
Here's a page on Oak's token module . AEM uses crx token module but how they work is essentially same. Since your credentials are passed to a single instance by a form based authentication handler the token is created only in one instance. The authentication handler page also has some details on the token and the cookie.
UPDATE:
With AEM 6.1 , the authentication can now be made stateless as long as the user exists on all the publish instances. This is done by using a encrypted cookie that can be decrypted by all publish instances when they share the same HMAC key. More information can be found here : https://docs.adobe.com/docs/en/aem/6-1/administer/security/encapsulated-token.html
i think it´s possible if you activate the clustering on your authors, the .token node will be replicated to all instances and while comparing the users token ressource and the cookie the identification succeeds, this is one of the benefits of the jcr philosophy :all is content
Enable encapsulated token option in OSGI. Then it will authenticate seamlessly. But there are 2 prerequisite or conditions to get it worked. One is to put the same HMAC key on all the instances and secondly the user should exist. if these 2 conditions are met then if you login on one stack and the second stack wont required authentication again.