Saturday, June 22, 2019

We continue with the threat modeling of Keycloak on Kubernetes

 Creating an ingress for the Keycloak service:
An ingress controller gives a service an externally reachable http/https-based URL while terminating SSL/TLS traffic. We don’t need to specify rules as an ingress without any rules sends the traffic to a default backend. The default backend is a configuration option of the ingress controller. This is called a Single Service Ingress. When we use a private key and a certificate specified in a K8s secret, we can secure the transport between the client and the ingress. Default Nginx ingress is sufficient in this regard.
Recommendation: A single service ingress specification for any service within Kubernetes is a simple Yaml configuration to be applied and serves to harden the security for the transport.
User account and authentication:
When user accounts and service accounts are independent and do not flow the security context between them, the overall user experience is not seamless. UAA was a technique used by CloudFoundry to facilitate the same identity to be used across internal and external operations.
Keycloak already supports OAuth access token retrieval for a user. Passing the token in payloads to internal services enables the security context to flow. Recommendation There is no need for a separate investment in this direction.
Recommendation: Unless the user context is specifically needed in the batch jobs and stream scopes, we can keep it all as internal in the beta release.

Conclusion:
Initial release of the product can simplify the threat model by internalizing all the components including the User Interface and allowing the trust boundary to be penetrated only with username/password while maintain all security components, artifacts and configurations as internal and detailed. In subsequent releases we can make each component robust as we strive to push the trust boundary to the application API.


uint GetElement(int [,] matrix, uint startrow, uint startcol, uint endrow, uint endcol, uint number)
{
while(startrow < endrow && startcol < endCol)
{
uint midrow = (startrow + endrow) / 2 ;
uint midcol = (startcol + endcol) / 2;

if (matrix[midrow, midcol] < number))
{
startrow = midrow;
startcol = midcol;
}
else
{
endrow = midrow;
endcol = midcol;
}
}
if (startrow == endrow && startcol == endcol)
{
  return matrix[startrow, startcol] < number ? matrix[startrow, startcol] : 0;
}
if ((startcol == endcol && startrow == endrow - 1) || (startrow == endrow && startcol == endcol - 1) )
{
  if (matrix[endrow, endcol] < number) return matrix[endrow, endcol];
  if (matrix[startrow, startcol] < number) return matrix [ startrow, startcol];
  return 0;
}
if (matrix[startrow, startcol] < number)
{
startrow = endrow;
startcol = endcol;
}
uint topright =  startcol - 1 > 0 && startrow - 1 > 0  ? GetElement(matrix, 0, startcol, startrow - 1, endcol, number) : 0;
uint bottomleft = startrow + 1 <= endrow && startcol - 1 > 0 ? GetElement(matrix, startrow + 1, 0, endrow, startcol - 1,
number) : 0;
if (topright < bottomleft)
  return bottomleft;
else
  return topright;
}


Friday, June 21, 2019

We continue discussing the keycloak deployment on Kubernetes.

Keycloak does not need to be in a standalone mode. It could be a cloud service. Both are facilitated by the architecture of the Kubernetes service broker. The requirements partly come from the type of Identity provider serviced by the application using the Kubernetes cluster. In the case when Keycloak is installed and run on the same cluster as the application, the server connection does not need to be hardened in the service broker representation within the service catalog.
Recommendation: we reserve the ClusterServiceBroker, ClusterServiceClass, ClusterServicePlan as singleton representations for the Keycloak service broker. Even the ServiceInstance and ServiceBinding could be singleton instance specific to the Keycloak service broker. This way there is only one secret that the Service catalog controller creates which can then be mounted into the Pods. This secret will store only the connection details and credentials for the Keycloak service broker. All registrations for clients and roles will be maintained in the same generic K8s resource reserved for use with the service broker. Although this is not urgent for Beta release, it will bring consistency going forward.

The open service broker API recognized that setting up capabilities within the cluster will be rather limiting. On the other hand provisioning it in the cloud will immensely help scalability. Therefore the OSBA API could become the gateway to the cloud for the Applications deployed on the cluster.

Thursday, June 20, 2019

We continue with the keycloak deployment on Kubernetes:
The Service catalog returns the details of the resource as a K8s secret. If the application persists the K8s secret on a mounted volume, care must be taken to mark the volumes as readOnly. 
Similarly, while Keycloak configuration is internal, it should be prevented from reconfiguration after the deployment.
The Service broker listens on port 9090 over http. Since this is internal, it has no TLS requirements. When the token passes the trust boundary, we rely on the kubectl interface to secure the communication with the API Server. As long as clients are communicating with kubectl or the API Server, this technique works well. In general, if the server and the clients communicate via TLS and they have verified the certificate chain, then there is little chance of token falling in wrong hands. The URL logging or https proxy are still vulnerabilities but the man in the middle attack is less of an issue if the client and the server exchange session id and keep track of each other's session id. As an API implementation, session Id's are largely site or application based and not the APIs concern but it’s good to validate based on session id if such is available.
Sessions are unique to the application. Even the client uses refresh tokens or re-authorizations to keep the session alive. At the API level, if the sessions were kept track of, it would not be tied to the OAuth revokes and re-authorizations, hence relying on session id alone is not preferable. At the same time, using session id as an additional parameter to confirm along with each authorization helps tighten security. It is safe to assume the same session prevalence until the next authorization or an explicit revoke.  By tying the checks exclusively to the token, we keep this streamlined to the protocol.
In the absence of session, we can use refresh tokens after token expiry. Since the refresh token is a protocol (RFC) intrinsic technique, it is already safe to use to prolong the period of access beyond token expiry time. Repeatedly acquiring a refresh token is the same as keeping a session alive. The above threat mitigation works regardless of the actual implementation of a notion of session.

Wednesday, June 19, 2019

We continue discussing Keycloak on Kubernetes. The Service catalog returns the details of the resource as a K8s secret. If the application persists the K8s secret on a mounted volume, care must be taken to mark the volumes as readOnly. 
Similarly, while Keycloak configuration is internal, it should be prevented from reconfiguration after the deployment.
The Service broker listens on port 9090 over http. Since this is internal, it has no TLS requirements. When the token passes the trust boundary, we rely on the kubectl interface to secure the communication with the API Server. As long as clients are communicating with kubectl or the API Server, this technique works well. In general, if the server and the clients communicate via TLS and they have verified the certificate chain, then there is little chance of token falling in wrong hands. The URL logging or https proxy are still vulnerabilities but the man in the middle attack is less of an issue if the client and the server exchange session id and keep track of each other's session id. As an API implementation, session Id's are largely site or application based and not the APIs concern but it’s good to validate based on session id if such is available.
Sessions are unique to the application. Even the client uses refresh tokens or re-authorizations to keep the session alive. At the API level, if the sessions were kept track of, it would not be tied to the OAuth revokes and re-authorizations, hence relying on session id alone is not preferable. At the same time, using session id as an additional parameter to confirm along with each authorization helps tighten security. It is safe to assume the same session prevalence until the next authorization or an explicit revoke.  By tying the checks exclusively to the token, we keep this streamlined to the protocol.
In the absence of session, we can use refresh tokens after token expiry. Since the refresh token is a protocol (RFC) intrinsic technique, it is already safe to use to prolong the period of access beyond token expiry time. Repeatedly acquiring a refresh token is the same as keeping a session alive. The above threat mitigation works regardless of the actual implementation of a notion of session.

Tuesday, June 18, 2019

We continue with the discussion of Keycloak deployment on Kubernetes:
This deployment consists of an identity provider together with the broker. In future, there may be more than one identity provider. A user goes to the identity provider to login. This is just how OAuth operates where all requests for user tokens are initiated by redirecting the user to the login screen of the identity provider. Since a user interface is involved the interaction between the user and the IDP is now subject to all the threats that a web interface faces. Threats such as cross site scripting, man-in-the-middle attacks, SQL injection attacks, cross-origin resource sharing and others are all vulnerabilities exploited from the client side. Enabling browser traffic to be over https mitigates only some of these concerns as transport is only a layer below the application logic.
We now turn towards the Keycloak Json file that describes the various configurations for the Keycloak. The Java adapter for Keycloak is described with attributes such as “auth-server-url", “ssl-required”, “cors-allowed-methods", “cors-exposed-headers", “bearer-only”, “expose-token”, “verify-token-audience", “disable-trust-manager", “trust-store”, “client-keystore”, “token-minimum-time-to-live" and “redirect-rewrite-rules". These options help harden security.
Using any generic Open ID Connect Resource provider is an alternative to using the Java adapter for Keycloak. However, the advantage of using Java adapter as opposed to the generic OIDC library, is that it facilitates tighter security with minimal code by use of configuration options. The adapter binds the platform with the framework so that the application and the clients can be secured. The configuration options provide all the parameters to tighten the security
Use cases:
There are only two use cases for the OIDC resource provider – first it allows applications to request token for a user. In this case an identity token containing the username and profile information is returned.  An access token containing the role mappings and authorization information is also returned. 
The second case is when a remote service requests token on behalf of the user. It is treated as a client and issued an access_token. 

Monday, June 17, 2019

Today we continue with the threat assessment of keycloak deployment on Kubernetes cluster.
Storing of the data exchanged from the system to the user is generally outside the trust boundary. If the data is tampered, hijacked or compromised, the activities within the trust boundary can be manipulated. This makes the system vulnerable and therefore validation of the data becomes important activity within each component.
The data usually comprises of a token along with attributes that are made available by the issuing Keycloak service broker in Json format. Since this is part of the OAuth protocol, the mechanisms of the protocol already mitigate security vulnerabilities pertaining to the data. It is just the handling of the data after the protocol has issued them that needs to be secured. Again, this falls outside the trust boundary and as such is largely on the user side of responsibilities. The system takes efforts only to validate the data. After validation, it is assumed that the token belongs to the identity to whom the token was issued. If the token is not hijacked, only registered and authorized users can take action on the system.
Tokens are not restricted to users. Client credential access grants tokens to clients from the issuing authority.  Clients and users are both registered so their requests are only honored if they can be looked up.
In the case of deployment of Keycloak service broker over Kubernetes clusters, we validate the integration between Keycloak service broker, the service catalog and the open service broker API. We assume each component is independently assessed with their STRIDE model and only secure the integration. Since the Keycloak service broker fits nicely into the open service broker API framework of Kubernetes, we can take it to be internal.
Therefore, we evaluate only the Keycloak deployment. This deployment consists of an identity provider together with the broker. In future, there may be more than one identity provider. A user goes to the identity provider to login. This is just how OAuth operates where all requests for user tokens are initiated by redirecting the user to the login screen of the identity provider. Since a user interface is involved the interaction between the user and the IDP is now subject to all the threats that a web interface faces. Threats such as cross site scripting, man-in-the-middle attacks, SQL injection attacks, cross-origin resource sharing and others are all vulnerabilities exploited from the client side. Enabling browser traffic to be over https mitigates only some of these concerns as transport is only a layer below the application logic.

Sunday, June 16, 2019

We continue discussing the STRIDE model of testing:
we apply how the different threats can arise by partitioning it between that which is within trust boundary and that which is outside.
When a user1 can behave like user2, that is considered spoofing. Possible defense might involve issuing tokens specific to users.
Tampering is when the user has successfully modified the token to her advantage.
Repudiation is when the user can hijack a valid token that the system cannot refute.
Denial of Service is when the user can tank the Identity provider (IDP) or the API server.
Elevation of privilege is when the user has compromised the IDP or the API server.
When we add Keycloak to the above Kubernetes authentication,
We add the following components:

In this case the interactions are deeper in the trust boundary where the Open Service broker API represents the API server in the earlier diagram.
When components go deeper within the trusted boundary, the security risk reduces. However this is just at the protocol between the components. It does not say anything about the layered communication between the components or how the request and response are protected.
API security mitigates most of these concerns with the help of request parameters and the use of encryption.
However, storing of the data exchanged from the system to the user is generally outside the trust boundary. If the data is tampered, hijacked or compromised, the activities within the trust boundary can be manipulated. This makes the system vulnerable and therefore validation of the data becomes important activity within each component.