diff --git a/authorizer/src/asapo_authorizer/authorization/authorization.go b/authorizer/src/asapo_authorizer/authorization/authorization.go
new file mode 100644
index 0000000000000000000000000000000000000000..768350e943f75b429406effb5b3a53ea1d551af6
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/authorization/authorization.go
@@ -0,0 +1,75 @@
+package authorization
+
+import (
+	"asapo_common/utils"
+	"encoding/json"
+	"github.com/rs/xid"
+	"time"
+)
+
+type Auth struct {
+	authHMAC utils.Auth
+	authHMACAdmin utils.Auth
+	authJWT utils.Auth
+}
+
+func NewAuth(authHMAC,authHMACAdmin,authJWT utils.Auth) *Auth {
+	return &Auth{authHMAC,authHMACAdmin,authJWT}
+}
+
+func (auth *Auth) AdminAuth() utils.Auth {
+	return auth.authHMACAdmin
+}
+
+func (auth *Auth) HmacAuth() utils.Auth {
+	return auth.authHMAC
+}
+
+func (auth *Auth) JWTAuth() utils.Auth {
+	return auth.authJWT
+}
+
+func subjectFromRequest(request TokenRequest) string {
+	for key,value := range request.Subject {
+		switch key {
+		case "beamline":
+			return "bl_" + value
+		case "beamtimeId":
+			return "bt_" + value
+		default:
+			return value
+		}
+	}
+	return ""
+}
+
+func (auth *Auth) PrepareUserJWTToken(request TokenRequest) (string, error) {
+	var claims utils.CustomClaims
+	var extraClaim utils.AccessTokenExtraClaim
+
+	claims.Subject = subjectFromRequest(request)
+
+	extraClaim.AccessType = request.AccessType
+	claims.ExtraClaims = &extraClaim
+	claims.SetExpiration(time.Duration(request.DaysValid*24) * time.Hour)
+	uid := xid.New()
+	claims.Id = uid.String()
+
+	return auth.authJWT.GenerateToken(&claims)
+
+}
+
+func UserTokenResponce(request TokenRequest, token string) []byte {
+	expires := ""
+	if request.DaysValid>0 {
+		expires = time.Now().Add(time.Duration(request.DaysValid*24) * time.Hour).UTC().Format(time.RFC3339)
+	}
+	answer := TokenResponce{
+		Token:      token,
+		AccessType: request.AccessType,
+		Sub:  subjectFromRequest(request),
+		Expires:  expires,
+	}
+	res, _ := json.Marshal(answer)
+	return res
+}
diff --git a/authorizer/src/asapo_authorizer/authorization/structs.go b/authorizer/src/asapo_authorizer/authorization/structs.go
new file mode 100644
index 0000000000000000000000000000000000000000..aeec3c550b2a5ef11694c94cc15358675f151604
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/authorization/structs.go
@@ -0,0 +1,14 @@
+package authorization
+
+type TokenRequest struct {
+	Subject    map[string]string
+	DaysValid  int
+	AccessType string
+}
+
+type TokenResponce struct {
+	Token      string
+	Sub        string
+	AccessType string
+	Expires    string
+}
diff --git a/authorizer/src/asapo_authorizer/cli/cli.go b/authorizer/src/asapo_authorizer/cli/cli.go
new file mode 100644
index 0000000000000000000000000000000000000000..0851d568c782b2d97f80894b3afd280f0c5a1b64
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/cli.go
@@ -0,0 +1,60 @@
+// Package contains asapo commands that can be executed from command line.
+// Every CommandXxxx function that is a member of a cmd struct processes asapo xxxx command
+package cli
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"strings"
+)
+
+var flHelp bool
+
+var outBuf io.Writer = os.Stdout
+
+func printHelp(f *flag.FlagSet) bool {
+	if flHelp {
+		f.Usage()
+		return true
+	} else {
+		return false
+	}
+}
+
+// DoCommand takes command name as a parameter and executes corresponding to this name cmd method
+func DoCommand(name string, args []string) error {
+	commandName := "Command" + strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
+	cmd := new(command)
+	commandName = strings.ReplaceAll(commandName,"-","_")
+	methodVal := reflect.ValueOf(cmd).MethodByName(commandName)
+	if !methodVal.IsValid() {
+		return errors.New("wrong "+ProgramName+" command: " + name + "\nType '"+os.Args[0]+" -help'")
+	}
+	cmd.name = strings.ReplaceAll(name,"-","_")
+	cmd.args = args
+
+	method := methodVal.Interface().(func() error)
+
+	return method()
+}
+
+// PrintAllCommands prints all available commands (found wihtin methods of cmd)
+func PrintAllCommands() {
+	fmt.Fprintln(outBuf, "\nCommands:")
+	cmd := new(command)
+	CmdType := reflect.TypeOf(cmd)
+	for i := 0; i < CmdType.NumMethod(); i++ {
+		methodVal := CmdType.Method(i)
+		if strings.HasPrefix(methodVal.Name, "Command") {
+			method := methodVal.Func.Interface().(func(*command) error)
+			cmd.name = strings.ToLower(methodVal.Name)[7:]
+			cmd.name = strings.ReplaceAll(cmd.name,"_","-")
+			cmd.args = []string{"description"}
+			method(cmd)
+		}
+	}
+}
diff --git a/authorizer/src/asapo_authorizer/cli/command.go b/authorizer/src/asapo_authorizer/cli/command.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f8fc4f556ff1e420de679d953eab89a3c194654
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/command.go
@@ -0,0 +1,43 @@
+package cli
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"os"
+)
+
+var ProgramName string
+
+// A command consists of a command name and arguments, passed to this command (all after program name ...)
+type command struct {
+	name string
+	args []string
+}
+
+// description prints description line and returns true if first command argument is "description".
+func (cmd *command) description(d string) bool {
+	if len(cmd.args) == 1 && cmd.args[0] == "description" {
+		fmt.Fprintf(outBuf, "   %-10s %s\n", cmd.name, d)
+		return true
+	}
+	return false
+}
+
+func (cmd *command) errBadOptions(err string) error {
+	return errors.New(ProgramName + " " + cmd.name + ": " + err + "\nType '" +os.Args[0] +" " + cmd.name + " -help'")
+}
+
+// createDefaultFlagset creates new flagset and adds default help behaviour.
+func (cmd *command) createDefaultFlagset(description, args string) *flag.FlagSet {
+
+	flags := flag.NewFlagSet(cmd.name, flag.ContinueOnError)
+	flags.BoolVar(&flHelp, "help", false, "Print usage")
+	flags.Usage = func() {
+		fmt.Fprintf(outBuf, "Usage:\t\n"+ProgramName+" %s "+args, cmd.name)
+		fmt.Fprintf(outBuf, "\n\n%s\n", description)
+		flags.PrintDefaults()
+	}
+
+	return flags
+}
diff --git a/authorizer/src/asapo_authorizer/cli/command_test.go b/authorizer/src/asapo_authorizer/cli/command_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b62788adea6f9f9ce0a3334ec8b2ea7ac3e4856e
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/command_test.go
@@ -0,0 +1,41 @@
+package cli
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_authorizer/server"
+	"asapo_common/utils"
+	"bytes"
+	"testing"
+	"github.com/stretchr/testify/assert"
+)
+
+var CommandTests = []struct {
+	cmd    command
+	ok bool
+	msg string
+}{
+	{command{"create-token", []string{"-type", "create-user-token", "-beamtime","123","-access-type","read","-duration-days","1"}}, true,"ok"},
+	{command{"dummy", []string{"description"}}, false,"wrong command"},
+}
+
+func TestCommand(t *testing.T) {
+	outBuf = new(bytes.Buffer)
+	server.Auth = authorization.NewAuth(utils.NewHMACAuth("secret"),utils.NewHMACAuth("secret"),utils.NewJWTAuth("secret"))
+
+	for _, test := range CommandTests {
+		outBuf.(*bytes.Buffer).Reset()
+		err := DoCommand(test.cmd.name, test.cmd.args)
+		if !test.ok {
+			assert.NotNil(t, err, "Should be error",test.msg)
+		} else {
+			assert.Nil(t, err, "Should be ok",test.msg)
+		}
+	}
+
+}
+
+func TestPrintAllCommands(t *testing.T) {
+	outBuf = new(bytes.Buffer)
+	PrintAllCommands()
+	assert.Contains(t, outBuf.(*bytes.Buffer).String(), "token", "all commands must have token")
+}
diff --git a/authorizer/src/asapo_authorizer/cli/create_token.go b/authorizer/src/asapo_authorizer/cli/create_token.go
new file mode 100644
index 0000000000000000000000000000000000000000..6481f22f2b012cff02b183fbcbf7a3873cfa356d
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/create_token.go
@@ -0,0 +1,146 @@
+package cli
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_authorizer/server"
+	"errors"
+	"os"
+	"fmt"
+	"asapo_common/utils"
+)
+
+type tokenFlags struct {
+	Type       string
+	AccessType string
+	Beamtime   string
+	Beamline   string
+	DaysValid  int
+}
+
+func generateToken(id string,secret string) string {
+	hmac := utils.NewHMACAuth(secret)
+	token,err := hmac.GenerateToken(&id)
+
+	if (err!=nil) {
+		fmt.Println(err.Error())
+	}
+	return token
+}
+
+func isUserRequest(reqType string) bool {
+ return reqType == "user-token"
+}
+
+func isAdminRequest(reqType string) bool {
+	return reqType == "admin-token"
+}
+
+
+func userTokenRequest(flags tokenFlags) (request authorization.TokenRequest, err error) {
+	if (flags.Beamline=="" && flags.Beamtime=="") || (flags.Beamline!="" && flags.Beamtime!="") {
+		return request,errors.New("beamtime or beamline must be set")
+	}
+	if flags.AccessType!="read" && flags.AccessType!="write" {
+		return request,errors.New("access type must be read of write")
+	}
+
+	if flags.DaysValid<=0 {
+		return request,errors.New("expiration period must be set")
+	}
+
+	request.Subject = make(map[string]string,1)
+	if (flags.Beamline!="") {
+		request.Subject["beamline"]=flags.Beamline
+	} else {
+		request.Subject["beamtimeId"]=flags.Beamtime
+	}
+	request.AccessType = flags.AccessType
+	request.DaysValid = flags.DaysValid
+
+	return
+}
+
+
+func adminTokenRequest(flags tokenFlags) (request authorization.TokenRequest, err error) {
+	if flags.Beamline+flags.Beamtime!="" {
+		return request,errors.New("beamtime and beamline must not be set for admin token")
+	}
+	if flags.AccessType!="create" && flags.AccessType!="revoke" && flags.AccessType!="list" {
+		return request,errors.New("access type must be create,revoke of list")
+	}
+	request.Subject = make(map[string]string,1)
+	request.Subject["user"]="admin"
+	request.AccessType = flags.AccessType
+	request.DaysValid = flags.DaysValid
+
+	return
+}
+
+// GenerateToken generates token for consumers
+func (cmd *command) CommandCreate_token() (err error) {
+	message_string := "Generate token"
+	if cmd.description(message_string) {
+		return nil
+	}
+
+	flags, err := cmd.parseTokenFlags(message_string)
+	if err != nil {
+		return err
+	}
+
+	request, err := getTokenRequest(flags)
+	if err != nil {
+		return err
+	}
+
+	token, err := server.Auth.PrepareUserJWTToken(request)
+	if err != nil {
+		return err
+	}
+
+	answer := authorization.UserTokenResponce(request, token)
+	fmt.Fprintf(outBuf, "%s\n", string(answer))
+	return nil
+}
+
+func getTokenRequest(flags tokenFlags) (request authorization.TokenRequest, err error) {
+	switch flags.Type {
+	case "user-token":
+		request, err = userTokenRequest(flags)
+	case "admin-token":
+		request, err = adminTokenRequest(flags)
+	default:
+		return authorization.TokenRequest{}, errors.New("wrong token type")
+	}
+	if err != nil {
+		return authorization.TokenRequest{}, err
+	}
+	return request, err
+}
+
+
+func (cmd *command) parseTokenFlags(message_string string) (tokenFlags, error) {
+
+	var flags tokenFlags
+	flagset := cmd.createDefaultFlagset(message_string, "")
+	flagset.StringVar(&flags.Type, "type", "", "token type")
+	flagset.StringVar(&flags.Beamtime, "beamtime", "", "beamtime for user token")
+	flagset.StringVar(&flags.Beamline, "beamline", "", "beamline for user token")
+	flagset.StringVar(&flags.AccessType, "access-type", "", "read/write for user token")
+	flagset.IntVar(&flags.DaysValid, "duration-days", 0, "token duration (in days)")
+
+
+	flagset.Parse(cmd.args)
+
+	if printHelp(flagset) {
+		os.Exit(0)
+	}
+
+	if flags.Type == "" {
+		return flags, errors.New("secret file missed ")
+	}
+
+
+	return flags, nil
+
+}
diff --git a/authorizer/src/asapo_authorizer/cli/create_token_test.go b/authorizer/src/asapo_authorizer/cli/create_token_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..68396195a23710daad4e1a8c8ed974b4eec8840d
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/create_token_test.go
@@ -0,0 +1,52 @@
+package cli
+
+import (
+	"asapo_authorizer/authorization"
+	"asapo_authorizer/server"
+	"asapo_common/utils"
+	"encoding/json"
+	"fmt"
+	"testing"
+
+	"bytes"
+	"github.com/stretchr/testify/assert"
+)
+
+var tokenTests = []struct {
+	cmd             command
+	ok              bool
+	tokenAccessType string
+	tokenSubject    string
+	tokenExpires bool
+	msg             string
+}{
+//	{command{args: []string{"-type"}}, false, "", "", "not enough parameters"},
+//	{command{args: []string{"-type", "user-token", "-beamtime","123","-access-type","read","-duration-days","10"}},
+//		true, "read", "bt_123", true,"user token ok"},
+	{command{args: []string{"-type", "admin-token","-access-type","create"}},
+		true, "create", "admin", false,"admin token ok"},
+}
+
+func TestGenerateToken(t *testing.T) {
+	outBuf = new(bytes.Buffer)
+	server.Auth = authorization.NewAuth(utils.NewHMACAuth("secret"),utils.NewHMACAuth("secret"),utils.NewJWTAuth("secret"))
+	for _, test := range tokenTests {
+		err := test.cmd.CommandCreate_token()
+		fmt.Println(err)
+		if !test.ok {
+			assert.NotNil(t, err, test.msg)
+			continue
+		}
+		assert.Nil(t, err, test.msg)
+		var token authorization.TokenResponce
+		json.Unmarshal(outBuf.(*bytes.Buffer).Bytes(), &token)
+		assert.Equal(t, test.tokenSubject, token.Sub, test.msg)
+		assert.Equal(t, test.tokenAccessType, token.AccessType, test.msg)
+		if test.tokenExpires {
+			assert.Equal(t, true, len(token.Expires)>0, test.msg)
+		} else {
+			assert.Empty(t, token.Expires, test.msg)
+		}
+
+	}
+}
diff --git a/authorizer/src/asapo_authorizer/cli/daemon.go b/authorizer/src/asapo_authorizer/cli/daemon.go
new file mode 100644
index 0000000000000000000000000000000000000000..46bf9a3e7bc4bdd1cb121bd21c819f21a9749921
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/cli/daemon.go
@@ -0,0 +1,18 @@
+package cli
+
+import (
+	"asapo_authorizer/server"
+)
+
+
+func (cmd *command) CommandDaemon() error {
+
+	message_string := "Start daemon (default)"
+	if cmd.description(message_string) {
+		return nil
+	}
+
+	server.Start()
+
+	return nil
+}
diff --git a/authorizer/src/asapo_authorizer/common/structs.go b/authorizer/src/asapo_authorizer/common/structs.go
new file mode 100644
index 0000000000000000000000000000000000000000..805d0c79aadd885ddb6ed76b1e678c10a63bbe45
--- /dev/null
+++ b/authorizer/src/asapo_authorizer/common/structs.go
@@ -0,0 +1 @@
+package common
diff --git a/authorizer/src/asapo_authorizer/main/authorizer.go b/authorizer/src/asapo_authorizer/main/authorizer.go
index 9f4329909333d6dac5c88966ccbc398497856941..57261418da9c80661c09aa8a5d57db7c2ea693e1 100644
--- a/authorizer/src/asapo_authorizer/main/authorizer.go
+++ b/authorizer/src/asapo_authorizer/main/authorizer.go
@@ -3,19 +3,22 @@
 package main
 
 import (
-	log "asapo_common/logger"
+	"asapo_authorizer/cli"
 	"asapo_authorizer/server"
+	log "asapo_common/logger"
 	"asapo_common/version"
 	"flag"
 	"os"
 )
 
-func PrintUsage() {
-	log.Fatal("Usage: " + os.Args[0] + " -config <config file>")
-}
+var (
+	flHelp = flag.Bool("help", false, "Print usage")
+)
 
 func main() {
-	var fname = flag.String("config", "", "config file path")
+	cli.ProgramName = "asapo-authorizer"
+
+	var fname = flag.String("config", "", "config file path (mandatory)")
 
 	if ret := version.ShowVersion(os.Stdout, "ASAPO Authorizer"); ret {
 		return
@@ -24,10 +27,16 @@ func main() {
 	log.SetSoucre("authorizer")
 
 	flag.Parse()
-	if *fname == "" {
-		PrintUsage()
+	if *flHelp {
+		flag.Usage()
+		cli.PrintAllCommands()
+		return
 	}
 
+	if *fname=="" {
+		log.Fatal("config file path is missed")
+
+	}
 	logLevel, err := server.ReadConfig(*fname)
 	if err != nil {
 		log.Fatal(err.Error())
@@ -35,5 +44,12 @@ func main() {
 
 	log.SetLevel(logLevel)
 
-	server.Start()
+	if len(flag.Args()) == 0 {
+		server.Start()
+	}
+
+	if err := cli.DoCommand(flag.Arg(0), flag.Args()[1:]); err != nil {
+		log.Fatal(err.Error())
+	}
+
 }
diff --git a/authorizer/src/asapo_authorizer/server/authorize.go b/authorizer/src/asapo_authorizer/server/authorize.go
index edcf0b703767f142d746a56235155bef6b942e91..89020bf127c793d08acfb010c759a6da98d3d444 100644
--- a/authorizer/src/asapo_authorizer/server/authorize.go
+++ b/authorizer/src/asapo_authorizer/server/authorize.go
@@ -155,10 +155,10 @@ func needHostAuthorization(creds SourceCredentials) bool {
 func authorizeByToken(creds SourceCredentials) error {
 	var token_expect string
 	if (creds.BeamtimeId != "auto") {
-		token_expect, _ = authHMAC.GenerateToken(&creds.BeamtimeId)
+		token_expect, _ = Auth.HmacAuth().GenerateToken(&creds.BeamtimeId)
 	} else {
 		key := "bl_" + creds.Beamline
-		token_expect, _ = authHMAC.GenerateToken(&key)
+		token_expect, _ = Auth.HmacAuth().GenerateToken(&key)
 	}
 
 	var err_string string
diff --git a/authorizer/src/asapo_authorizer/server/authorize_test.go b/authorizer/src/asapo_authorizer/server/authorize_test.go
index 01983cb0034e90fdde52446947d95718be9ab37b..8fdf09e583f0ec95aeaf007e04ae23933cf02397 100644
--- a/authorizer/src/asapo_authorizer/server/authorize_test.go
+++ b/authorizer/src/asapo_authorizer/server/authorize_test.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_authorizer/common"
 	"asapo_authorizer/ldap_client"
 	"asapo_common/utils"
@@ -15,14 +16,14 @@ import (
 )
 
 func prepareToken(payload string) string{
-	authHMAC = utils.NewHMACAuth("secret")
-	token, _ := authHMAC.GenerateToken(&payload)
+	Auth = authorization.NewAuth(utils.NewHMACAuth("secret"),nil,nil)
+	token, _ := Auth.HmacAuth().GenerateToken(&payload)
 	return token
 }
 
 func prepareAdminToken(payload string) string{
-	authHMACAdmin = utils.NewHMACAuth("secret_admin")
-	token, _ := authHMACAdmin.GenerateToken(&payload)
+	Auth = authorization.NewAuth(nil,utils.NewHMACAuth("secret_admin"),nil)
+	token, _ := Auth.AdminAuth().GenerateToken(&payload)
 	return token
 }
 
@@ -205,7 +206,7 @@ var authTests = [] struct {
 func TestAuthorize(t *testing.T) {
 	ldapClient = mockClient
 	allowBeamlines([]beamtimeMeta{})
-
+	Auth = authorization.NewAuth(utils.NewHMACAuth("secret"),utils.NewHMACAuth("secret"),utils.NewJWTAuth("secret"))
 	expected_uri := "expected_uri"
 	expected_base := "expected_base"
 	allowed_ips := []string{"127.0.0.1"}
diff --git a/authorizer/src/asapo_authorizer/server/folder_token.go b/authorizer/src/asapo_authorizer/server/folder_token.go
index f693640448b5ccac87d3fc54aaddcf4bd3fe95f9..be3d6b7ec7e693f9c67b17913dd6d0ada394f5d7 100644
--- a/authorizer/src/asapo_authorizer/server/folder_token.go
+++ b/authorizer/src/asapo_authorizer/server/folder_token.go
@@ -30,7 +30,7 @@ func prepareJWTToken(request folderTokenRequest) (string,error) {
 	extraClaim.RootFolder = request.Folder
 	claims.ExtraClaims = &extraClaim
 	claims.SetExpiration(time.Duration(settings.FolderTokenDurationMin) * time.Minute)
-	return authJWT.GenerateToken(&claims)
+	return Auth.JWTAuth().GenerateToken(&claims)
 
 }
 
@@ -39,7 +39,7 @@ func folderTokenResponce(token string) []byte{
 }
 
 func checkBeamtimeToken(request folderTokenRequest) error {
-	token_expect, _ := authHMAC.GenerateToken(&request.BeamtimeId)
+	token_expect, _ := Auth.HmacAuth().GenerateToken(&request.BeamtimeId)
 	var err_string string
 	if request.Token != token_expect {
 		err_string = "wrong token for beamtime " + request.BeamtimeId
diff --git a/authorizer/src/asapo_authorizer/server/folder_token_test.go b/authorizer/src/asapo_authorizer/server/folder_token_test.go
index 2b45e61c25040a4b2f0816f7502556686fcea11c..61e7d8f5ae09ad8de9f5b4502f888dc8223d7557 100644
--- a/authorizer/src/asapo_authorizer/server/folder_token_test.go
+++ b/authorizer/src/asapo_authorizer/server/folder_token_test.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_common/utils"
 	"github.com/stretchr/testify/assert"
 	"io/ioutil"
@@ -31,6 +32,8 @@ func TestFolderToken(t *testing.T) {
 	allowBeamlines([]beamtimeMeta{})
 	settings.RootBeamtimesFolder ="."
 	settings.CurrentBeamlinesFolder="."
+	Auth = authorization.NewAuth(utils.NewHMACAuth("secret"),utils.NewHMACAuth("secret"),utils.NewJWTAuth("secret"))
+
 	os.MkdirAll(filepath.Clean("tf/gpfs/bl1/2019/data/test"), os.ModePerm)
 	os.MkdirAll(filepath.Clean("tf/gpfs/bl1/2019/data/test_online"), os.ModePerm)
 
@@ -41,7 +44,6 @@ func TestFolderToken(t *testing.T) {
 	defer 	os.RemoveAll("bl1")
 
 	for _, test := range fodlerTokenTests {
-		authJWT = utils.NewJWTAuth("secret")
 		abs_path:=settings.RootBeamtimesFolder + string(filepath.Separator)+test.root_folder
 		request :=  makeRequest(folderTokenRequest{abs_path,test.beamtime_id,test.token})
 		if test.status == http.StatusBadRequest {
diff --git a/authorizer/src/asapo_authorizer/server/issue_token.go b/authorizer/src/asapo_authorizer/server/issue_token.go
index 898783522ed6c76a7cec0faa794f809cd0b8bcbb..aa863eb3a85bdb00d705959b411baa293f2c7839 100644
--- a/authorizer/src/asapo_authorizer/server/issue_token.go
+++ b/authorizer/src/asapo_authorizer/server/issue_token.go
@@ -1,100 +1,56 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	log "asapo_common/logger"
 	"asapo_common/utils"
-	"encoding/json"
 	"errors"
-	"github.com/rs/xid"
 	"net/http"
-	"time"
 )
 
-type userTokenRequest struct {
-	BeamtimeId   string
-	Beamtimeline string
-	DaysValid    int
-	Role         string
-}
-
-type userToken struct {
-	Token      string
-	AccessType string
-	Expires    string
-}
-
-func prepareUserJWTToken(request userTokenRequest) (string, error) {
-	var claims utils.CustomClaims
-	var extraClaim utils.AccessTokenExtraClaim
-
-	if request.Beamtimeline != "" {
-		claims.Subject = "bl_" + request.Beamtimeline
-	} else {
-		claims.Subject = "bt_" + request.BeamtimeId
-	}
 
-	extraClaim.Role = request.Role
-	claims.ExtraClaims = &extraClaim
-	claims.SetExpiration(time.Duration(request.DaysValid*24) * time.Hour)
-	uid := xid.New()
-	claims.Id = uid.String()
-
-	return authJWT.GenerateToken(&claims)
-
-}
-
-func extractUserTokenrequest(r *http.Request) (userTokenRequest, error) {
-	var request userTokenRequest
-	err := utils.ExtractRequest(r, &request)
+func extractUserTokenrequest(r *http.Request) (request authorization.TokenRequest, err error) {
+	err = utils.ExtractRequest(r, &request)
 	if err != nil {
-		return userTokenRequest{}, err
+		return request, err
 	}
 
-	if request.BeamtimeId == "" && request.Beamtimeline == "" {
-		return userTokenRequest{}, errors.New("missing beamtime/beamline")
+	if request.Subject["beamtimeId"] == "" && request.Subject["beamline"] == "" {
+		return request, errors.New("missing beamtime/beamline")
 	}
 
-	if request.BeamtimeId != "" && request.Beamtimeline != "" {
-		return userTokenRequest{}, errors.New("set only one of beamtime/beamline")
+	if request.Subject["beamtimeId"] != "" && request.Subject["beamline"] != "" {
+		return request, errors.New("set only one of beamtime/beamline")
 	}
 
-	if request.Role != "read" && request.Role != "write" {
-		return userTokenRequest{}, errors.New("wrong role " + request.Role)
+	if request.AccessType != "read" && request.AccessType != "write" {
+		return request, errors.New("wrong access type " + request.AccessType)
 	}
 
 	return request, nil
 }
 
-func userTokenResponce(request userTokenRequest, token string) []byte {
-	answer := userToken{
-		Token:      token,
-		AccessType: request.Role,
-		Expires:    time.Now().Add(time.Duration(request.DaysValid*24) * time.Hour).UTC().Format(time.RFC3339),
-	}
-	res, _ := json.Marshal(answer)
-	return res
-}
 
-func authorisedUserToken(w http.ResponseWriter, r *http.Request) {
-	authHMACAdmin.ProcessAuth(routeUserToken, "admin")(w, r)
+func routeAuthorisedTokenIssue(w http.ResponseWriter, r *http.Request) {
+	Auth.AdminAuth().ProcessAuth(issueUserToken, "admin")(w, r)
 }
 
-func routeUserToken(w http.ResponseWriter, r *http.Request) {
+func issueUserToken(w http.ResponseWriter, r *http.Request) {
 	request, err := extractUserTokenrequest(r)
 	if err != nil {
 		utils.WriteServerError(w, err, http.StatusBadRequest)
 		return
 	}
 
-	token, err := prepareUserJWTToken(request)
+	token, err := Auth.PrepareUserJWTToken(request)
 	if err != nil {
 		utils.WriteServerError(w, err, http.StatusInternalServerError)
 		return
 	}
 
-	log.Debug("generated user token for beamtime " + request.BeamtimeId)
+	log.Debug("generated user token ")
 
-	answer := userTokenResponce(request, token)
+	answer := authorization.UserTokenResponce(request, token)
 	w.WriteHeader(http.StatusOK)
 	w.Write(answer)
 }
diff --git a/authorizer/src/asapo_authorizer/server/issue_token_test.go b/authorizer/src/asapo_authorizer/server/issue_token_test.go
index f85e92b35c4d8138154681d117e955d6c2394462..26de51a2e4397b4b0e44827252d83da00e6b3555 100644
--- a/authorizer/src/asapo_authorizer/server/issue_token_test.go
+++ b/authorizer/src/asapo_authorizer/server/issue_token_test.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_common/utils"
 	"encoding/json"
 	"fmt"
@@ -12,9 +13,8 @@ import (
 )
 
 var  IssueTokenTests = [] struct {
-	beamtimeId string
-	beamline string
-	subject string
+	requestSubject map[string]string
+	tokenSubject string
 	role string
 	validDays int
 	adminToken string
@@ -22,33 +22,33 @@ var  IssueTokenTests = [] struct {
 	status int
 	message string
 }{
-	{"test", "","bt_test","read",180,prepareAdminToken("admin"),"aaa",http.StatusOK,"read for beamtime"},
-	{"test", "","bt_test","read",90,prepareAdminToken("admin"),"aaa",http.StatusOK,"write for beamtime"},
-	{"", "test","bl_test","read",180,prepareAdminToken("admin"),"aaa",http.StatusOK,"read for beamline"},
-	{"test", "test","","read",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"both beamline/beamtime given"},
-	{"", "","","read",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"beamline or beamtime not given"},
-	{"test", "","","bla",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"wrong role"},
-	{"test", "","","read",180,prepareAdminToken("bla"),"",http.StatusUnauthorized,"wrong admin token"},
+	{map[string]string{"beamtimeId":"test"},"bt_test","read",180,prepareAdminToken("admin"),"aaa",http.StatusOK,"read for beamtime"},
+	{map[string]string{"beamtimeId":"test"},"bt_test","read",90,prepareAdminToken("admin"),"aaa",http.StatusOK,"write for beamtime"},
+	{map[string]string{"beamline":"test"},"bl_test","read",180,prepareAdminToken("admin"),"aaa",http.StatusOK,"read for beamline"},
+	{map[string]string{"blabla":"test"},"","read",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"beamline or beamtime not given"},
+	{map[string]string{"beamtimeId":"test"},"","bla",180,prepareAdminToken("admin"),"",http.StatusBadRequest,"wrong role"},
+	{map[string]string{"beamtimeId":"test"},"","read",180,prepareAdminToken("bla"),"",http.StatusUnauthorized,"wrong admin token"},
 }
 
 func TestIssueToken(t *testing.T) {
-	authJWT = utils.NewJWTAuth("secret")
-	authHMACAdmin = utils.NewHMACAuth("secret_admin")
+	authJWT := utils.NewJWTAuth("secret")
+	authHMACAdmin := utils.NewHMACAuth("secret_admin")
+	Auth = authorization.NewAuth(nil,authHMACAdmin,authJWT)
 	for _, test := range IssueTokenTests {
-		request :=  makeRequest(userTokenRequest{test.beamtimeId,test.beamline,test.validDays,test.role})
+		request :=  makeRequest(authorization.TokenRequest{test.requestSubject,test.validDays,test.role})
 		w := doPostRequest("/admin/issue",request,authHMACAdmin.Name()+" "+test.adminToken)
 		if w.Code == http.StatusOK {
 			body, _ := ioutil.ReadAll(w.Body)
-			var token userToken
+			var token authorization.TokenResponce
 			json.Unmarshal(body,&token)
 			claims,_ := utils.CheckJWTToken(token.Token,"secret")
 			cclaims,_:= claims.(*utils.CustomClaims)
 			var extra_claim utils.AccessTokenExtraClaim
 			utils.MapToStruct(claims.(*utils.CustomClaims).ExtraClaims.(map[string]interface{}), &extra_claim)
-			assert.Equal(t, cclaims.Subject , test.subject, test.message)
+			assert.Equal(t, cclaims.Subject , test.tokenSubject, test.message)
 			assert.True(t, cclaims.ExpiresAt-time.Now().Unix()>int64(test.validDays)*24*60*60-10, test.message)
 			assert.True(t, cclaims.ExpiresAt-time.Now().Unix()<int64(test.validDays)*24*60*60+10, test.message)
-			assert.Equal(t, extra_claim.Role , test.role, test.message)
+			assert.Equal(t, extra_claim.AccessType, test.role, test.message)
 			assert.NotEmpty(t, cclaims.Id , test.message)
 		} else {
 			body, _ := ioutil.ReadAll(w.Body)
diff --git a/authorizer/src/asapo_authorizer/server/listroutes.go b/authorizer/src/asapo_authorizer/server/listroutes.go
index 7282f7a7498c9a82892317953fa32d89c872a9af..e640c8a8acb799afc725cea2a0993d7155e45cf9 100644
--- a/authorizer/src/asapo_authorizer/server/listroutes.go
+++ b/authorizer/src/asapo_authorizer/server/listroutes.go
@@ -27,6 +27,6 @@ var listRoutes = utils.Routes{
 		"User Token",
 		"POST",
 		"/admin/issue",
-		authorisedUserToken,
+		routeAuthorisedTokenIssue,
 	},
 }
diff --git a/authorizer/src/asapo_authorizer/server/server.go b/authorizer/src/asapo_authorizer/server/server.go
index 6e5c6d8a6f7721cc8e4bf663939e39dc15c4af9e..0efe071ad23d66922020a4c4cc785c53416f1536 100644
--- a/authorizer/src/asapo_authorizer/server/server.go
+++ b/authorizer/src/asapo_authorizer/server/server.go
@@ -1,8 +1,8 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_authorizer/ldap_client"
-	"asapo_common/utils"
 )
 
 type  beamtimeMeta struct {
@@ -32,7 +32,5 @@ type serverSettings struct {
 
 var settings serverSettings
 var ldapClient ldap_client.LdapClient
-var authHMAC utils.Auth
-var authHMACAdmin utils.Auth
-var authJWT utils.Auth
+var Auth *authorization.Auth
 
diff --git a/authorizer/src/asapo_authorizer/server/server_nottested.go b/authorizer/src/asapo_authorizer/server/server_nottested.go
index c9f2667bcd5d9e93699e6053e41b96de04db420d..01de58ec8778d6aecd74413a38057a64f0cf5156 100644
--- a/authorizer/src/asapo_authorizer/server/server_nottested.go
+++ b/authorizer/src/asapo_authorizer/server/server_nottested.go
@@ -3,6 +3,7 @@
 package server
 
 import (
+	"asapo_authorizer/authorization"
 	"asapo_authorizer/ldap_client"
 	log "asapo_common/logger"
 	"asapo_common/utils"
@@ -20,17 +21,17 @@ func Start() {
 	log.Fatal(http.ListenAndServe(":"+strconv.Itoa(settings.Port), http.HandlerFunc(mux.ServeHTTP)))
 }
 
-func createAuth() (utils.Auth, utils.Auth, utils.Auth, error) {
+func createAuth() (*authorization.Auth,error) {
 	secret, err := utils.ReadFirstStringFromFile(settings.UserSecretFile)
 	if err != nil {
-		return nil, nil, nil, err
+		return nil, err
 	}
 	adminSecret, err := utils.ReadFirstStringFromFile(settings.AdminSecretFile)
 	if err != nil {
-		return nil, nil, nil, err
+		return nil, err
 	}
 
-	return utils.NewHMACAuth(adminSecret), utils.NewHMACAuth(secret), utils.NewJWTAuth(secret), nil
+	return authorization.NewAuth(utils.NewHMACAuth(adminSecret), utils.NewHMACAuth(secret), utils.NewJWTAuth(secret)),nil
 }
 
 func ReadConfig(fname string) (log.Level, error) {
@@ -51,7 +52,7 @@ func ReadConfig(fname string) (log.Level, error) {
 	}
 
 	var err error
-	authHMACAdmin, authHMAC, authJWT, err = createAuth()
+	Auth, err = createAuth()
 	if err != nil {
 		return log.FatalLevel, err
 	}
diff --git a/common/go/src/asapo_common/utils/structs.go b/common/go/src/asapo_common/utils/structs.go
index e758e6aede6f57affa937ee0bb25240df7beeff0..2280212e1079483cdc27da3b838be3514f2a965a 100644
--- a/common/go/src/asapo_common/utils/structs.go
+++ b/common/go/src/asapo_common/utils/structs.go
@@ -5,5 +5,5 @@ type FolderTokenTokenExtraClaim struct {
 }
 
 type AccessTokenExtraClaim struct {
-	Role string
+	AccessType string
 }