Security - ge-semtk/semtk GitHub Wiki

Security Overview

SemTK security is based upon the assumption that you may deploy SemTK services behind a reverse proxy. For security to work effectively, the following must happen:

  • all incoming ports are blocked except via a reverse proxy
  • proxy authenticates and adds the header: user_name to all downstream calls

There are two layers of security described in the following sections:

  1. Job security - insures that users only interact with jobs they own
  2. Graph security - controls read/write access to graphs (not yet released)

Reserved security graphs, users, groups

These graphs, users, groups may have special privileges and may be created for unit testing. These user names should not be allowed by the reverse proxy graphs and groups should be avoided:

  • users starting with testuser_
  • user groups starting with securityTest
  • the graph "http://securityTest"

Operating without security

  • If there is no security proxy such that the user_name header is found, all REST calls will be authenticated to anonymous.
  • If the auth.graphName property is missing or empty, no attempt at authorization will take place.

Security vars in ENV_OVERRIDE

# read security settings from here
export AUTH_SETTINGS_FILE_PATH=/path/auth_settings.json
# log security events here
export AUTH_LOG_PATH=/path/auth.log
# re-read the auth settings file this frequently
export AUTH_REFRESH_SECONDS=120
# this header (added by your security proxy) holds the user name
export AUTH_USERNAME_KEY=sso
# this header (added by your security proxy) holds the user name
export AUTH_GROUP_KEY=group

Settings File

Note reserved words:

  • OTHER_GRAPHS- any graph not otherwise specified
  • ALL_USERS - group of all users
{
	"groups": [
		{
			"name": "kings",
			"members": ["user27king"]
		},
		{
			"name": "readers1",
			"members": ["user10", "user11"]
		},
		{
			"name": "writers1",
			"members": ["user27king", "user10"]
		}
	],
	"graphs" [
		{
			"name": "http://test/graph",
			"readGroups": ["readers1"],
			"writeGroups": ["writers1"]
		},
		{
			"name": "http://jobs/admin",
			"readIDMGroups":  ["g0000000"],
			"writeIDMGroups": ["g0000000"],
		},
		{
			"name": "OTHER_GRAPHS",
			"readGroups": ["ALL_USERS"],
			"writeGroups": []
		}
 
	]
}

Job Security

The status and results services enforce authorization such that once a job is created, only its owner can perform any action pertaining to it.

Security JAVA code

Security-related objects are found in the SparqlGraphLibrary package com.ge.research.semtk.auth except for HeadersManager.

com.ge.research.semtk.sprintutillib.headers.HeadersManager

This insulates the non-spring-boot modules from sprintframwork.http.HttpHeaders by translating them into a com.ge.research.semtk.auth.HeaderTable before beginning the authentication process. This starts the authentication process for any REST endpoint by adding an endpoint parameter

public JSONObject endpointName(..., @RequestHeader HttpHeaders headers) { HeadersManager.setHeaders(header)

This reads the appropriate headers and authenticates the thread with ThreadAuthenticator.

ThreadAuthenticator.java

This class has static functions to parse HttpHeaders and hold the user_name in a ThreadLocal variable.

The ThreadAuthenticator works with the RestClient to make sure that additional SemTK calls made out of this thread have the appropriate headers for downstream ThreadAuthenticators.

Passing headers in rest controllers

  • rest controller endpoint needs parameter: @RequestHeader HttpHeaders headers
  • first line of rest controller endpoint: HeadersManager.setHeaders(headers);

These headers are presumed to be provided by a proxy that has done authentication. If they're missing, the thread runs as 'anonymous'.

The RestController class will ensure that headers are passed through to additional REST calls.

Authenticating a sub-thread

  • thread constructor should have: this.headerTable = ThreadAuthenticator.getThreadHeaderTable();
  • thread run() should start with: ThreadAuthenticator.authenticateThisThread(this.headerTable);

AuthorizationManager.java

This reads and caches information from the auth properties files, and makes decisions on whether a thread is allowed to access a resource. If not, it will throw an AuthorizationException

Most commonly, the SparqlEndpointInterface uses the AuthorizationManager to authorize all queries based on the user and the graph names.

"Super-user" queries

SemTK code often has to access graphs that do not have general read/write permissions. These include the results graph. Library code deployed behind the proxy can use AuthorizationManager.nextQuerySemtkSuper() to indicate the next query will be executed as SemTk, and not as the authenticated user.