From d7f3b13a941c03ebd9343abd9c33b2c578cc78fb Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 11 Feb 2019 21:38:44 +0100 Subject: [PATCH 1/9] initial commit for review --- API/auth.proto | 209 +++++++++++++++++++++++++++++++++++++++++++++ authAPI/auth.proto | 149 -------------------------------- 2 files changed, 209 insertions(+), 149 deletions(-) create mode 100644 API/auth.proto delete mode 100644 authAPI/auth.proto diff --git a/API/auth.proto b/API/auth.proto new file mode 100644 index 0000000..18e9374 --- /dev/null +++ b/API/auth.proto @@ -0,0 +1,209 @@ +syntax = "proto3"; + +import "google/api/annotations.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "protoc-gen-swagger/options/annotations.proto"; +import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/lyft/protoc-gen-validate/validate/validate.proto"; + +package yabslabs.auth.api.v1; +option go_package = "API"; + +option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Authorization Service for yabs"; + version: "1.0"; + contact: { + url: "https://github.com/yabslabs/auth" + }; + }; + + schemes: HTTPS; + + consumes: "application/json"; + consumes: "application/grpc"; + + produces: "application/json"; + produces: "application/grpc"; +}; + +service AuthService { + rpc AddUser(AddUserRequest) returns (AddUserResponse) { + option (google.api.http) = { + post: "/users" + body: "*" + }; + } + + rpc GetUser(GetUserRequest) returns (GetUserResponse) { + option (google.api.http) = { + get: "/users" + }; + } + + rpc GetUserById(GetUserByIdRequest) returns (GetUserByIdResponse) { + option (google.api.http) = { + get: "/users/{id}" + }; + } + + rpc FilterUser(FilterUserRequest) returns (FilterUserResponse) { + option (google.api.http) = { + post: "/users/_search" + body: "*" + }; + } + + rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) { + option (google.api.http) = { + put: "/users/{id}" + }; + } + + rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse) { + option (google.api.http) = { + delete: "/users/{id}" + }; + } + + rpc AddUserToGroup(AddUserToGroupRequest) returns (AddUserToGroupResponse) { + option (google.api.http) = { + post: "/groups/{id}/users/{user_id}" + }; + } + + rpc GetUserFromGroup(GetUserFromGroupRequest) returns (GetUserFromGroupResponse) { + option (google.api.http) = { + post: "/groups/{id}/users/{user_id}" + }; + } + + rpc DeleteUserFromGroup(DeleteUserFromGroupRequest) returns (DeleteUserFromGroupResponse) { + option (google.api.http) = { + delete: "/groups/{id}/users/{user_id}" + }; + } + + rpc AddUserToProject(AddUserToProjectRequest) returns (AddUserToProjectResponse) { + option (google.api.http) = { + post: "/projects/{id}/users/{user_id}" + }; + } + + rpc GetUserFromProject(GetUserFromProjectRequest) returns (GetUserFromProjectResponse) { + option (google.api.http) = { + post: "/projects/{id}/users/{user_id}" + }; + } + + rpc DeleteUserFromProject(DeleteUserFromProjectRequest) returns (DeleteUserFromProjectResponse) { + option (google.api.http) = { + delete: "/projects/{id}/users/{user_id}" + }; + } + + rpc //change password + + rpc //reset password + + rpc //add two factor + + rpc //reset two factor +} + +message AddUserRequest { + +} + +message AddUserResponse { + +} + +message GetUserRequest { + +} + +message GetUserResponse { + +} + +message GetUserByIdRequest { + +} + +message GetUserByIdResponse { + +} + +message FilterUserRequest { + +} + +message FilterUserResponse { + +} + +message UpdateUserRequest { + +} + +message UpdateUserResponse { + +} + +message DeleteUserRequest { + +} + +message DeleteUserResponse { + +} + +message AddUserToGroupRequest { + +} + +message AddUserToGroupResponse { + +} + +message GetUserFromGroupRequest { + +} + +message GetUserFromGroupResponse { + +} + +message DeleteUserFromGroupRequest { + +} + +message DeleteUserFromGroupResponse { + +} + +message AddUserToProjectRequest { + +} + +message AddUserToProjectResponse { + +} + +message GetUserFromProjectRequest { + +} + +message GetUserFromProjectResponse { + +} + +message DeleteUserFromProjectRequest { + +} + +message DeleteUserFromProjectResponse { + +} \ No newline at end of file diff --git a/authAPI/auth.proto b/authAPI/auth.proto deleted file mode 100644 index 357808d..0000000 --- a/authAPI/auth.proto +++ /dev/null @@ -1,149 +0,0 @@ -syntax = "proto3"; - -import "google/api/annotations.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; -import "protoc-gen-swagger/options/annotations.proto"; -import "github.com/mwitkow/go-proto-validators/validator.proto"; -import "github.com/lyft/protoc-gen-validate/validate/validate.proto"; - -package yabslabs.auth.api.v1; -option go_package = "authAPI"; - -option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { - info: { - title: "Authorization Service of SecureConnect"; - version: "1.0"; - contact: { - url: "https://github.com/yabslabs/auth" - }; - }; - - schemes: HTTPS; - - consumes: "application/json"; - consumes: "application/grpc"; - - produces: "application/json"; - produces: "application/grpc"; -}; - -service AuthService { - - option (yabslabs.auth.api.v1.service_auth) = { - resource_name: "AUTH-V1" - }; -} - -message UserID{ - string id = 1; -} - -message UserRequest{ - string id =1 ; - string firstname =2; - string lastname = 3; - string password = 4; - string email = 5 [(validate.rules).string.email = true]; - string seq = 6; -} - -message User{ - string id =1; - string firstname = 2; - string lastname = 3; - string password = 4; - string email = 5 [(validate.rules).string.email = true]; - google.protobuf.Timestamp creationDate = 6; - google.protobuf.Timestamp changeDate = 7; - string seq = 8; -} - -message Users{ - repeated User users = 1; -} - -message GroupRequest{ - string id = 1; - string name = 2; - repeated string subgroups = 3; - string seq = 4; - repeated string projects = 5; - repeated string users = 6; -} - -message Group{ - string id = 1; - string name = 2; - repeated Group subgroups = 3; - google.protobuf.Timestamp creationDate = 4; - google.protobuf.Timestamp changeDate = 5; - string seq = 6; - repeated Project projects = 7; - repeated User users = 8; -} - -message Groups{ - repeated Group groups = 1; -} -message ProejctID{ - string id = 1; -} - -message ProjectRequest{ - string id = 1; - string name = 2; - string seq = 3; -} - -message Project{ - string id = 1; - string name = 2; - google.protobuf.Timestamp creationDate = 3; - google.protobuf.Timestamp changeDate = 4; - string seq = 5; -} - -message Projects{ - repeated Project projects = 1; -} - -message AuthorizationID{ - string id = 1; -} - -message AuthorizationRequest{ - string id = 1; - string groupid = 2; - string roleid = 3; - string userid = 4; - string seq = 5; -} - -message Authorization{ - string id = 1; - Group group = 2; - Role role = 3; - User user = 4; - google.protobuf.Timestamp creationDate = 5; - string seq = 6; -} - -message Authorizations{ - repeated Authorization authorizations = 1; -} - -message RoleID{ - string id = 1; -} - -message Role{ - string id = 1; - string name = 2; - google.protobuf.Timestamp creationDate = 3; - string seq = 4; -} - -message Roles{ - repeated Role roles = 1; -} \ No newline at end of file From f895b6730911907f61cfafecc349b4be9d5b748a Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 11 Feb 2019 21:57:42 +0100 Subject: [PATCH 2/9] review changes --- API/auth.proto | 71 ++++++++++++-------------------------------------- 1 file changed, 16 insertions(+), 55 deletions(-) diff --git a/API/auth.proto b/API/auth.proto index 18e9374..a1bcd42 100644 --- a/API/auth.proto +++ b/API/auth.proto @@ -8,7 +8,7 @@ import "github.com/mwitkow/go-proto-validators/validator.proto"; import "github.com/lyft/protoc-gen-validate/validate/validate.proto"; package yabslabs.auth.api.v1; -option go_package = "API"; +option go_package = "api"; option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { info: { @@ -58,6 +58,7 @@ service AuthService { rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) { option (google.api.http) = { put: "/users/{id}" + body: "*" }; } @@ -67,39 +68,23 @@ service AuthService { }; } - rpc AddUserToGroup(AddUserToGroupRequest) returns (AddUserToGroupResponse) { - option (google.api.http) = { - post: "/groups/{id}/users/{user_id}" - }; - } - - rpc GetUserFromGroup(GetUserFromGroupRequest) returns (GetUserFromGroupResponse) { - option (google.api.http) = { - post: "/groups/{id}/users/{user_id}" - }; - } - - rpc DeleteUserFromGroup(DeleteUserFromGroupRequest) returns (DeleteUserFromGroupResponse) { + rpc AddMemberToGroup(AddMemberToGroupRequest) returns (AddMemberToGroupResponse) { option (google.api.http) = { - delete: "/groups/{id}/users/{user_id}" - }; - } - - rpc AddUserToProject(AddUserToProjectRequest) returns (AddUserToProjectResponse) { - option (google.api.http) = { - post: "/projects/{id}/users/{user_id}" + post: "/groups/{id}/members/{user_id}" + body: "*" }; } - rpc GetUserFromProject(GetUserFromProjectRequest) returns (GetUserFromProjectResponse) { + rpc GetMemberFromGroup(GetMemberFromGroupRequest) returns (GetMemberFromGroupResponse) { option (google.api.http) = { - post: "/projects/{id}/users/{user_id}" + post: "/groups/{id}/members/{user_id}" + body: "*" }; } - rpc DeleteUserFromProject(DeleteUserFromProjectRequest) returns (DeleteUserFromProjectResponse) { + rpc DeleteMemberFromGroup(DeleteMemberFromGroupRequest) returns (DeleteMemberFromGroupResponse) { option (google.api.http) = { - delete: "/projects/{id}/users/{user_id}" + delete: "/groups/{id}/members/{user_id}" }; } @@ -160,50 +145,26 @@ message DeleteUserResponse { } -message AddUserToGroupRequest { +message AddMemberToGroupRequest { } -message AddUserToGroupResponse { +message AddMemberToGroupResponse { } -message GetUserFromGroupRequest { +message GetMemberFromGroupRequest { } -message GetUserFromGroupResponse { +message GetMemberFromGroupResponse { } -message DeleteUserFromGroupRequest { +message DeleteMemberFromGroupRequest { } -message DeleteUserFromGroupResponse { - -} +message DeleteMemberFromGroupResponse { -message AddUserToProjectRequest { - -} - -message AddUserToProjectResponse { - -} - -message GetUserFromProjectRequest { - -} - -message GetUserFromProjectResponse { - -} - -message DeleteUserFromProjectRequest { - -} - -message DeleteUserFromProjectResponse { - } \ No newline at end of file From ee30434190477e0bb81d6b60f7ca42d56bda79f4 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 11 Feb 2019 22:30:26 +0100 Subject: [PATCH 3/9] few details --- API/auth.proto | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/API/auth.proto b/API/auth.proto index a1bcd42..629c693 100644 --- a/API/auth.proto +++ b/API/auth.proto @@ -70,21 +70,21 @@ service AuthService { rpc AddMemberToGroup(AddMemberToGroupRequest) returns (AddMemberToGroupResponse) { option (google.api.http) = { - post: "/groups/{id}/members/{user_id}" + post: "/groups/{group_id}/members/{user_id}" body: "*" }; } rpc GetMemberFromGroup(GetMemberFromGroupRequest) returns (GetMemberFromGroupResponse) { option (google.api.http) = { - post: "/groups/{id}/members/{user_id}" + post: "/groups/{group_id}/members/{user_id}" body: "*" }; } rpc DeleteMemberFromGroup(DeleteMemberFromGroupRequest) returns (DeleteMemberFromGroupResponse) { option (google.api.http) = { - delete: "/groups/{id}/members/{user_id}" + delete: "/groups/{group_id}/members/{user_id}" }; } @@ -167,4 +167,30 @@ message DeleteMemberFromGroupRequest { message DeleteMemberFromGroupResponse { +} + +message Group { + Header header = 1; //API Header from yabs/api/core.proto + Metadata metadata = 2; //API Metadata from yabs/api/core.proto + Members members = 3; +} + +message Groups { + repeated group = 1; +} + +message Member { + string id = 1; +} + +message Members { + repeated member = 1; +} + +message Role { + string id = 1; +} + +message Roles { + repeated role = 1; } \ No newline at end of file From 87ac0414014f90b5457a3ce7882c1320ddefec34 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 11 Feb 2019 22:57:02 +0100 Subject: [PATCH 4/9] latest changes form slack discussion --- API/auth.proto | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/API/auth.proto b/API/auth.proto index 629c693..9aab635 100644 --- a/API/auth.proto +++ b/API/auth.proto @@ -88,13 +88,13 @@ service AuthService { }; } - rpc //change password + //change password - rpc //reset password + //reset password - rpc //add two factor + //add two factor - rpc //reset two factor + //reset two factor } message AddUserRequest { @@ -172,7 +172,8 @@ message DeleteMemberFromGroupResponse { message Group { Header header = 1; //API Header from yabs/api/core.proto Metadata metadata = 2; //API Metadata from yabs/api/core.proto - Members members = 3; + string id = 3; + Members members = 4; } message Groups { @@ -189,8 +190,21 @@ message Members { message Role { string id = 1; + string name = 2; + string description = 3; } message Roles { repeated role = 1; +} + +message Authorization { + string id = 1; + Group group = 2; + Role group = 3; + Member member = 4; +} + +message Authorizations { + Authorization authorization = 1; } \ No newline at end of file From d398dbdbdecb0bd1e71a31b45113595bbb6b5089 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Tue, 12 Feb 2019 22:23:12 +0100 Subject: [PATCH 5/9] add auth and change mgmt --- API/auth.proto | 256 ++++++++++++++++++++++++++----------------------- API/mgmt.proto | 219 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+), 122 deletions(-) create mode 100644 API/mgmt.proto diff --git a/API/auth.proto b/API/auth.proto index 9aab635..8b0dfa7 100644 --- a/API/auth.proto +++ b/API/auth.proto @@ -1,18 +1,13 @@ syntax = "proto3"; -import "google/api/annotations.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; -import "protoc-gen-swagger/options/annotations.proto"; -import "github.com/mwitkow/go-proto-validators/validator.proto"; -import "github.com/lyft/protoc-gen-validate/validate/validate.proto"; +// schema tags are required for application/x-www-form-urlencoded package yabslabs.auth.api.v1; option go_package = "api"; option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { info: { - title: "Authorization Service for yabs"; + title: "Authorization Service of yabs"; version: "1.0"; contact: { url: "https://github.com/yabslabs/auth" @@ -29,182 +24,199 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { }; service AuthService { - rpc AddUser(AddUserRequest) returns (AddUserResponse) { - option (google.api.http) = { - post: "/users" - body: "*" - }; - } - rpc GetUser(GetUserRequest) returns (GetUserResponse) { + // OIDC discovery endpoint + // provides information about this service + rpc GetConfiguration (google.protobuf.Empty) returns (OidcConfiguration) { option (google.api.http) = { - get: "/users" + get: "/.well-known/openid-configuration" }; } - rpc GetUserById(GetUserByIdRequest) returns (GetUserByIdResponse) { + // OIDC token endpoint, returns token(s) + // can be used for: + // - code exchange (exchange oidc auth code to appropiate tokens: 'authorization_code') + // - issue tokens (ex. access token for services, etc... ex. grant_types: 'client_credentials', 'password', 'urn:yabs:iam:grant_type:role_token') + // - exchange tokens (ex. to obtain an ob-token: 'urn:ietf:params:oauth:grant-type:token-exchange', 'urn:yabs:iam:grant_type:ob_token') + // supported grant types are exposed via the discovery endpoint. + // The following types are included: + // - client_credentials (request token for a service) + // - authorization_code (exchange a user-code for the corresponding tokens) + // - password (authorize a user directly; only permitted clients, needs role ResourceOwnerCredentialsGrantType, usage should be as limited as possible) + // - urn:ietf:params:oauth:grant-type:token-exchange (token exchange => get ob token) + // - urn:yabs:iam:grant_type:ob_token (on behalf token for a user to call a service) + // - urn:yabs:iam:grant_type:role_token (obtain a role token: get roles of apps inside a token) + // Client-Authorization can be done via Basic, Token or Body. + // For security reasons Token should be preferred. + // Client-Authorization is needed for all grant types expect client_credentials. + rpc GetAuthToken (AuthTokenRequest) returns (AuthTokenResponse) { option (google.api.http) = { - get: "/users/{id}" + post: "/token/auth" + body: "*" }; } - rpc FilterUser(FilterUserRequest) returns (FilterUserResponse) { + // corresponding endpoint for oidc request with grant type client_credentials + // should be used to obtain a token for a client/service. Does not support users. + // Client-Credentials can be sent via Basic or Body. For security reasons Basic should be preferred. + rpc GetAccessToken (AccessTokenRequest) returns (TokenResponse) { option (google.api.http) = { - post: "/users/_search" - body: "*" + post: "/token/access" + body: "*" }; } - rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) { + // corresponding endpoint for oidc request with grant type urn:yabs:iam:grant_type:role_token + // should be used to obtain a roletoken for specified apps. + // Client needs to authenticated. + rpc GetRoleToken (RoleTokenRequest) returns (TokenResponse) { option (google.api.http) = { - put: "/users/{id}" - body: "*" + post: "/token/roles" + body: "*" }; } - rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse) { + // corresponding endpoint for oidc request with grant type urn:yabs:iam:grant_type:ob_token or urn:ietf:params:oauth:grant-type:token-exchange + // should be used to obtain an ob token to call another service on behalf of a user. + // Client needs to authenticated. + rpc GetObToken (ObTokenRequest) returns (TokenResponse) { option (google.api.http) = { - delete: "/users/{id}" + post: "/token/ob" + body: "*" }; } - rpc AddMemberToGroup(AddMemberToGroupRequest) returns (AddMemberToGroupResponse) { - option (google.api.http) = { - post: "/groups/{group_id}/members/{user_id}" + // OIDC introspect endpoint + // validates a token, client needs to be authenticated. + rpc IntrospectToken (IntrospectTokenRequest) returns (IntrospectTokenResponse) { + option (google.api.http) = { + post: "/token/introspect" body: "*" }; } - rpc GetMemberFromGroup(GetMemberFromGroupRequest) returns (GetMemberFromGroupResponse) { + // OIDC Keys endpoint + // returns the public keys used to sign the tokens + rpc GetKeys (google.protobuf.Empty) returns (Keys) { option (google.api.http) = { - post: "/groups/{group_id}/members/{user_id}" - body: "*" + get: "/keys" }; } - rpc DeleteMemberFromGroup(DeleteMemberFromGroupRequest) returns (DeleteMemberFromGroupResponse) { + // OIDC UserInfo endpoint + // returns information about the current user + // user needs to be authenticated via token + rpc GetUserInfo (google.protobuf.Empty) returns (User) { option (google.api.http) = { - delete: "/groups/{group_id}/members/{user_id}" + get: "/me" }; - } - - //change password - - //reset password - - //add two factor - - //reset two factor -} - -message AddUserRequest { - -} - -message AddUserResponse { - -} - -message GetUserRequest { - -} - -message GetUserResponse { - -} -message GetUserByIdRequest { + //this needs an auth methode + } } -message GetUserByIdResponse { - +message Keys { + repeated Key keys = 1; } -message FilterUserRequest { - +message Key { + string use = 1; + string kty = 2; + string kid = 3; + string alg = 4; + string n = 5; + string e = 6; + string d = 9; + string p = 7; + string q = 8; } -message FilterUserResponse { - +message AccessTokenRequest { + string client_id = 1; + string client_secret = 2; + repeated string scope = 3; } -message UpdateUserRequest { - +message RoleTokenRequest { + string subject_token = 1 [(validator.field) = {string_not_empty: true}]; + repeated string apps = 2 [(validator.field) = {repeated_count_min: 1}]; } -message UpdateUserResponse { - +message ObTokenRequest { + string subject_token = 1 [(validator.field) = {string_not_empty: true}]; + string resource = 2 [(validator.field) = {string_not_empty: true}]; } -message DeleteUserRequest { - +message TokenResponse { + string token = 1; + int64 expires_in = 2; } -message DeleteUserResponse { +message AuthTokenRequest { + string grant_type = 1 [(gogoproto.moretags) = "schema:\"grant_type\"", (validator.field) = {string_not_empty: true}]; -} - -message AddMemberToGroupRequest { - -} + // client auth via body, basic or token + string client_id = 2 [(gogoproto.moretags) = "schema:\"client_id\""]; + string client_secret = 3 [(gogoproto.moretags) = "schema:\"client_secret\""]; -message AddMemberToGroupResponse { + // grant type authorization_code + string code = 4 [(gogoproto.moretags) = "schema:\"code\""]; + string redirect_uri = 5 [(gogoproto.moretags) = "schema:\"redirect_uri\""]; -} + // grant type client_credentials + repeated string scope = 6 [(gogoproto.moretags) = "schema:\"scope\""]; -message GetMemberFromGroupRequest { + // grant type ob_token/urn:ietf:params:oauth:grant-type:token-exchange, role_token + string subject_token = 7 [(gogoproto.moretags) = "schema:\"subject_token\""]; + string subject_token_type = 8 [(gogoproto.moretags) = "schema:\"subject_token_type\""]; -} + // grant type role_token + repeated string apps = 9 [(gogoproto.moretags) = "schema:\"apps\""]; -message GetMemberFromGroupResponse { + // grant type ob_token/urn:ietf:params:oauth:grant-type:token-exchange + string resource = 11 [(gogoproto.moretags) = "schema:\"resource\""]; + // grant type password + string username = 12 [(gogoproto.moretags) = "schema:\"username\""]; + string password = 13 [(gogoproto.moretags) = "schema:\"password\""]; } -message DeleteMemberFromGroupRequest { - -} - -message DeleteMemberFromGroupResponse { - -} - -message Group { - Header header = 1; //API Header from yabs/api/core.proto - Metadata metadata = 2; //API Metadata from yabs/api/core.proto - string id = 3; - Members members = 4; -} - -message Groups { - repeated group = 1; -} - -message Member { - string id = 1; -} - -message Members { - repeated member = 1; -} +message AuthTokenResponse { + string access_token = 1 [(gogoproto.moretags) = "schema:\"access_token\""]; + string id_token = 2 [(gogoproto.moretags) = "schema:\"id_token\""]; + string token_type = 3 [(gogoproto.moretags) = "schema:\"token_type\""]; + int64 expires_in = 4 [(gogoproto.moretags) = "schema:\"expires_in\""]; -message Role { - string id = 1; - string name = 2; - string description = 3; + // token exchange + string issued_token_type = 5 [(gogoproto.moretags) = "schema:\"issued_token_type\""]; } -message Roles { - repeated role = 1; +message IntrospectTokenRequest { + string token = 1; } -message Authorization { - string id = 1; - Group group = 2; - Role group = 3; - Member member = 4; +message IntrospectTokenResponse { + bool active = 1; + string sub = 2; + int64 exp = 3; } -message Authorizations { - Authorization authorization = 1; +message OidcConfiguration { + string issuer = 1; + string authorization_endpoint = 2; + string token_endpoint = 3; + string introspection_endpoint = 4; + string userinfo_endpoint = 5; + string end_session_endpoint = 6; + string check_session_iframe = 7; + string jwks_uri = 8; + repeated string scopes_supported = 9; + repeated string response_types_supported = 10; + repeated string response_modes_supported = 11; + repeated string grant_types_supported = 12; + repeated string subject_types_supported = 13; + repeated string id_token_signing_alg_values_supported = 14; + repeated string token_endpoint_auth_methods_supported = 15; + repeated string claims_supported = 16; } \ No newline at end of file diff --git a/API/mgmt.proto b/API/mgmt.proto new file mode 100644 index 0000000..8ba13ca --- /dev/null +++ b/API/mgmt.proto @@ -0,0 +1,219 @@ +syntax = "proto3"; + +package yabslabs.mgmt.api.v1; +option go_package = "api"; + +option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Authorization Management Service for yabs"; + version: "1.0"; + contact: { + url: "https://github.com/yabslabs/auth" + }; + }; + + schemes: HTTPS; + + consumes: "application/json"; + consumes: "application/grpc"; + + produces: "application/json"; + produces: "application/grpc"; +}; + +service AuthService { + + rpc AddUser(AddUserRequest) returns (AddUserResponse) { + option (google.api.http) = { + post: "/users" + body: "*" + }; + } + + rpc GetUser(GetUserRequest) returns (GetUserResponse) { + option (google.api.http) = { + get: "/users" + }; + } + + rpc GetUserById(GetUserByIdRequest) returns (GetUserByIdResponse) { + option (google.api.http) = { + get: "/users/{id}" + }; + } + + rpc FilterUser(FilterUserRequest) returns (FilterUserResponse) { + option (google.api.http) = { + post: "/users/_search" + body: "*" + }; + } + + rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) { + option (google.api.http) = { + put: "/users/{id}" + body: "*" + }; + } + + rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse) { + option (google.api.http) = { + delete: "/users/{id}" + }; + } + + rpc AddMemberToGroup(AddMemberToGroupRequest) returns (AddMemberToGroupResponse) { + option (google.api.http) = { + post: "/groups/{group_id}/members/{user_id}" + body: "*" + }; + } + + rpc GetMemberFromGroup(GetMemberFromGroupRequest) returns (GetMemberFromGroupResponse) { + option (google.api.http) = { + post: "/groups/{group_id}/members/{user_id}" + body: "*" + }; + } + + rpc DeleteMemberFromGroup(DeleteMemberFromGroupRequest) returns (DeleteMemberFromGroupResponse) { + option (google.api.http) = { + delete: "/groups/{group_id}/members/{user_id}" + }; + } + + //change password + + //reset password + + //add two factor + + //reset two factor +} + +message AddUserRequest { + +} + +message AddUserResponse { + +} + +message GetUserRequest { + +} + +message GetUserResponse { + +} + +message GetUserByIdRequest { + +} + +message GetUserByIdResponse { + +} + +message FilterUserRequest { + +} + +message FilterUserResponse { + +} + +message UpdateUserRequest { + +} + +message UpdateUserResponse { + +} + +message DeleteUserRequest { + +} + +message DeleteUserResponse { + +} + +message AddMemberToGroupRequest { + +} + +message AddMemberToGroupResponse { + +} + +message GetMemberFromGroupRequest { + +} + +message GetMemberFromGroupResponse { + +} + +message DeleteMemberFromGroupRequest { + +} + +message DeleteMemberFromGroupResponse { + +} + +message Group { + Header header = 1; //API Header from yabs/api/core.proto + Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + Members members = 4; +} + +message Groups { + repeated group = 1; +} + +message Member { + string id = 1; + User user = 2; +} + +message Members { + repeated member = 1; +} + +message Role { + string id = 1; + string name = 2; + string description = 3; +} + +message Roles { + repeated role = 1; +} + +message Authorization { + string id = 1; + Group group = 2; + Role group = 3; + Member member = 4; +} + +message Authorizations { + Authorization authorization = 1; +} + +message User { + string sub = 1; + string preferred_username = 2; + string name = 3; + string family_name = 4; + string given_name = 5; + + string email = 6; + bool email_verified = 7; + + string phone_number = 8; + bool phone_number_verified = 9; +} \ No newline at end of file From 01526274d43d8119784ce777dfe7c46c62318fde Mon Sep 17 00:00:00 2001 From: Stefan Benz Date: Tue, 12 Feb 2019 23:54:11 +0100 Subject: [PATCH 6/9] added severall endpoints, filled out messages and some corr. --- API/mgmt.proto | 429 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 379 insertions(+), 50 deletions(-) diff --git a/API/mgmt.proto b/API/mgmt.proto index 8ba13ca..0cac8a8 100644 --- a/API/mgmt.proto +++ b/API/mgmt.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +import "github.com/yabslabs/yabs/API/core.proto"; + package yabslabs.mgmt.api.v1; option go_package = "api"; @@ -22,27 +24,21 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { }; service AuthService { - - rpc AddUser(AddUserRequest) returns (AddUserResponse) { +//User + rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) { option (google.api.http) = { post: "/users" body: "*" }; } - rpc GetUser(GetUserRequest) returns (GetUserResponse) { - option (google.api.http) = { - get: "/users" - }; - } - rpc GetUserById(GetUserByIdRequest) returns (GetUserByIdResponse) { option (google.api.http) = { get: "/users/{id}" }; } - rpc FilterUser(FilterUserRequest) returns (FilterUserResponse) { + rpc FilterUsers(FilterUserRequest) returns (FilterUserResponse) { option (google.api.http) = { post: "/users/_search" body: "*" @@ -62,6 +58,60 @@ service AuthService { }; } + rpc ChangePassword(ChangePasswordRequest) returns (ChangePasswordResponse) { + option (google.api.http) = { + post: "/users/{id}/_changepw" + body: "*" + }; + } + + rpc OverwritePassword(OverwritePasswordRequest) returns (OverwritePasswordResponse) { + option (google.api.http) = { + post: "/users/{id}/_overwritepw" + body: "*" + }; + } + +//Group + rpc CreateGroup(CreateGroupRequest) returns (CreateGroupResponse) { + option (google.api.http) = { + post: "/groups" + body: "*" + }; + } + + rpc GetGroupById(GetGroupByIdRequest) returns (GetGroupByIdResponse) { + option (google.api.http) = { + get: "/groups/{id}" + }; + } + + rpc FilterGroups(FilterGroupRequest) returns (FilterGroupResponse) { + option (google.api.http) = { + post: "/groups/_search" + body: "*" + }; + } + + rpc UpdateGroup(UpdateGroupRequest) returns (UpdateGroupResponse) { + option (google.api.http) = { + put: "/groups/{id}" + body: "*" + }; + } + + rpc DeleteGroup(DeleteGroupRequest) returns (DeleteGroupResponse) { + option (google.api.http) = { + delete: "/groups/{id}" + }; + } +// Member + rpc GetAllGroupMembers(google.protobuf.Empty) returns (Users) { + option (google.api.http) = { + get: "/groups/{group_id}/members" + }; + } + rpc AddMemberToGroup(AddMemberToGroupRequest) returns (AddMemberToGroupResponse) { option (google.api.http) = { post: "/groups/{group_id}/members/{user_id}" @@ -81,106 +131,380 @@ service AuthService { delete: "/groups/{group_id}/members/{user_id}" }; } +// Subgroup + rpc AddSubgroupToGroup(AddSubgroupToGroupRequest) returns (AddSubgroupToGroupResponse) { + option (google.api.http) = { + post: "/groups/{group_id}/subgroup/{subgroup_id}" + body: "*" + }; + } - //change password + rpc GetSubgroupFromGroup(GetSubgroupFromGroupRequest) returns (GetSubgroupFromGroupResponse) { + option (google.api.http) = { + post: "/groups/{group_id}/subgroup/{subgroup_id}" + body: "*" + }; + } - //reset password + rpc DeleteSubgroupFromGroup(DeleteSubgroupFromGroupRequest) returns (DeleteSubgroupFromGroupResponse) { + option (google.api.http) = { + delete: "/groups/{group_id}/subgroup/{subgroup_id}" + }; + } - //add two factor +// Roles + rpc GetRoles(google.protobuf.Empty) returns (Roles) { + option (google.api.http) = { + get: "/roles" + }; + } + +//Authorizations + rpc GetAuthorizationByUser(GetAuthorizationByUserRequest) returns (GetAuthorizationByUserResponse) { + option (google.api.http) = { + get: "/users/{id}/authorizations" + }; + } + rpc GetAuthorizationByGroup(GetAuthorizationByGroupRequest) returns (GetAuthorizationByGroupResponse) { + option (google.api.http) = { + get: "/groups/{id}/authorizations" + }; + } + + rpc CreateAuthorization(CreateAuthorizationRequest) returns (CreateAuthorizationResponse) { + option (google.api.http) = { + post: "/authorizations" + body: "*" + }; + } + + rpc UpdateAuthorizations(UpdateAuthorizationRequest) returns (UpdateAuthorizationResponse) { + option (google.api.http) = { + put: "/authorizations/{id}" + body: "*" + }; + } + + rpc DeleteAuthorization(DeleteAuthorizationRequest) returns (DeleteAuthorizationResponse) { + option (google.api.http) = { + delete: "/authorizations/{id}" + }; + } + //add two factor //reset two factor + //delete two factor + //verify two factor } - -message AddUserRequest { - +message GetAuthorizationByUserRequest { + string id = 1; +} +message GetAuthorizationByUserResponse { + repeated Authorization authorizations = 1; +} +message GetAuthorizationByGroupRequest { + string id = 1; +} +message GetAuthorizationByGroupResponse { + repeated Authorization authorizations = 1; +} +message CreateAuthorizationRequest { + string group_id = 1; + string role_id = 2; + string user_id = 3; +} +message CreateAuthorizationResponse { + string id = 1; + Group group = 2; + Role role = 3; + User user = 4; +} +message UpdateAuthorizationRequest { + string authorization_id = 1; + string group_id = 2; + string role_id = 3; + string user_id = 4; +} +message UpdateAuthorizationResponse { + string id = 1; + Group group = 2; + Role role = 3; + User user = 4; +} +message DeleteAuthorizationRequest { + string id = 1; +} +message DeleteAuthorizationResponse { + string id = 1; + Group group = 2; + Role role = 3; + User user = 4; } -message AddUserResponse { -} +message CreateUserRequest { + string preferred_username = 1; + string familyname = 2; + string givenname = 3; + + string email = 4; -message GetUserRequest { + string phone_number = 5; + string password = 6; + string hash_function = 7; } -message GetUserResponse { +message CreateUserResponse { + string id = 1; + string preferred_username = 2; + string familyname = 3; + string givenname = 4; + + string email = 5; + bool email_verified = 6; + string phone_number = 7; + bool phone_number_verified = 8; } message GetUserByIdRequest { + string id = 1; } message GetUserByIdResponse { + string id = 1; + string preferred_username = 2; + string familyname = 3; + string givenname = 4; + string email = 5; + bool email_verified = 6; + + string phone_number = 7; + bool phone_number_verified = 8; } message FilterUserRequest { - +// dynamic filter } message FilterUserResponse { - + uint64 total_results = 1; + uint64 read_results = 2; + uint64 count = 3; + repeated User users = 4; } message UpdateUserRequest { + string id = 1; + string preferred_username = 2; + string familyname = 3; + string givenname = 4; + + string email = 5; + bool email_verified = 6; + string phone_number = 7; + bool phone_number_verified = 8; } message UpdateUserResponse { + string id = 1; + string preferred_username = 2; + string familyname = 3; + string givenname = 4; + string email = 5; + bool email_verified = 6; + + string phone_number = 7; + bool phone_number_verified = 8; } message DeleteUserRequest { - + string id = 1; } message DeleteUserResponse { + string id = 1; + string preferred_username = 2; + string familyname = 3; + string givenname = 4; + + string email = 5; + bool email_verified = 6; + string phone_number = 7; + bool phone_number_verified = 8; } -message AddMemberToGroupRequest { - +message ChangePasswordRequest { + string id = 1; + string old_password = 2; + string new_password1 = 3; + string new_password2 = 4; + string hash_function = 5; } -message AddMemberToGroupResponse { +message ChangePasswordResponse { + string id = 1; + PasswordState state = 2; +} +enum PasswordState { + NONE = 0; + ACTIVE = 1; + INITIAL = 2; + DELETED = 3; +} + +message OverwritePasswordRequest { + string id = 1; + string hash_function = 5; + string password = 2; +} + +message OverwritePasswordResponse { + string id = 1; + PasswordState state = 2; +} +message CreateGroupRequest { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto +} +message CreateGroupResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; +} +message GetGroupByIdRequest { + string id = 1; +} +message GetGroupByIdResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; +} +message FilterGroupRequest { +// dynamic filter +} +message FilterGroupResponse { + uint64 total_results = 1; + uint64 read_results = 2; + uint64 count = 3; + repeated Group groups = 4; +} +message UpdateGroupRequest { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; +} +message UpdateGroupResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; +} +message DeleteGroupRequest { + string id = 1; +} +message DeleteGroupResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; } -message GetMemberFromGroupRequest { +message AddMemberToGroupRequest { + string group_id = 1; + string user_id = 2; +} +message AddMemberToGroupResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; } -message GetMemberFromGroupResponse { +message GetMemberFromGroupRequest { + string group_id = 1; + string user_id = 2; +} +message GetMemberFromGroupResponse { + string id = 1; + User member = 2; } message DeleteMemberFromGroupRequest { - + string group_id = 1; + string user_id = 2; } message DeleteMemberFromGroupResponse { - + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; } -message Group { - Header header = 1; //API Header from yabs/api/core.proto - Metadata metadata = 2; //API Metadata from yabs/api/core.proto + +message AddSubgroupToGroupRequest { + string group_id = 1; + string subgroup_id = 2; +} +message AddSubgroupToGroupResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto string id = 3; - Members members = 4; + repeated User members = 4; + repeated Group subgroups = 5; } -message Groups { - repeated group = 1; +message GetSubgroupFromGroupRequest { + string group_id = 1; + string subgroup_id = 2; } -message Member { +message GetSubgroupFromGroupResponse { string id = 1; - User user = 2; + Group group = 2; +} + +message DeleteSubgroupFromGroupRequest { + string group_id = 1; + string subgroup_id = 2; +} + +message DeleteSubgroupFromGroupResponse { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; } -message Members { - repeated member = 1; +message Group { + yabs.core.api.v1.Header header = 1; //API Header from yabs/api/core.proto + yabs.core.api.v1.Metadata metadata = 2; //API Metadata from yabs/api/core.proto + string id = 3; + repeated User members = 4; + repeated Group subgroups = 5; +} + +message Groups { + repeated Group groups = 1; } message Role { @@ -190,14 +514,14 @@ message Role { } message Roles { - repeated role = 1; + repeated Role roles = 1; } message Authorization { string id = 1; Group group = 2; - Role group = 3; - Member member = 4; + Role role = 3; + User user = 4; } message Authorizations { @@ -205,15 +529,20 @@ message Authorizations { } message User { - string sub = 1; + string id = 1; string preferred_username = 2; - string name = 3; - string family_name = 4; - string given_name = 5; + string familyname = 3; + string givenname = 4; + + string email = 5; + bool email_verified = 6; - string email = 6; - bool email_verified = 7; + string phone_number = 7; + bool phone_number_verified = 8; + + string password = 9; +} - string phone_number = 8; - bool phone_number_verified = 9; +message Users { + repeated User users = 1; } \ No newline at end of file From 66305c94c9fbeb3598c49c26f9d3201c2438ec4a Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 13 Feb 2019 14:07:27 +0100 Subject: [PATCH 7/9] initial auth api design --- API/authn.proto | 129 +++++++++++++++++++++++++++++++++ API/{auth.proto => oidc.proto} | 4 +- API/saml.proto | 28 +++++++ 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 API/authn.proto rename API/{auth.proto => oidc.proto} (99%) create mode 100644 API/saml.proto diff --git a/API/authn.proto b/API/authn.proto new file mode 100644 index 0000000..28307ba --- /dev/null +++ b/API/authn.proto @@ -0,0 +1,129 @@ +syntax = "proto3"; + +// schema tags are required for application/x-www-form-urlencoded + +package yabslabs.auth.authn.api.v1; +option go_package = "api"; + +option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Authorization Service of yabs"; + version: "1.0"; + contact: { + url: "https://github.com/yabslabs/auth" + }; + }; + + schemes: HTTPS; + + consumes: "application/json"; + consumes: "application/grpc"; + + produces: "application/json"; + produces: "application/grpc"; +}; + +service AuthnService { + + // IDP Connection + ///////////////// + rpc AuthNRequest (AuthNRequest) returns (AuthNResponse) { + option (google.api.http) = { + post: "/authn" + body: "*" + }; + + } + + // Login GUI API + ///////////////// + rpc VerifyUserNamePassword (VerifyUserNamePasswordRequest) returns (VerifyUserNamePasswordResponse) { + option (google.api.http) = { + post: "/authn/verify/userpassword" + body: "*" + }; + } + + rpc VerifyMultiFactor (VerifyMultiFactorRequest) returns (VerifyMultiFactorResponse) { + option (google.api.http) = { + post: "/authn/verify/factors/{id}" + body: "*" + }; + } + + + +} + +message AuthNRequest { + string id = 1; + string scope = 2; +} + +message AuthNResponse { + string id = 1; + string scopes = 2; + AuthNStatus auth_n_status = 3; +} + +enum AuthNStatus { + DENIED = 0; + SUCESSFULL = 1; +} + +message VerifyUserNamePasswordRequest { + string id = 1; + string username = 2; + string password = 3; +} + +message VerifyUserNamePasswordResponse { + string id = 1; + bool factor_required = 2; + Factors factors = 3; + VerifyUserNamePasswordStatus status = 4; +} + +enum VerifyUserNamePasswordStatus { + DENIED = 0; + SUCESSFULL = 1; + // We can add hints like password expired here +} + +//IMHO this should come from the mgmt API +message Factor { + string id = 1; + FactorType factor_type = 2; +} + +//IMHO this should come from the mgmt API +message Factors { + repeated factor = 1; +} + +//IMHO this should come from the mgmt API +enum FactorType { + SMS = 0; + OTP = 1; + TELEGRAM = 2; + FBMESSENGER = 3; + CTAP1 = 4; //webauthn uf2 keys + CTAP2 = 5; //webauthn fido2 keys +} + +message VerifyMultiFactorRequest { + string id = 1; + //We need object for the different type of factos, becuase they do not all use the same mechanics +} + +message VerifyMultiFactorResponse { + string id = 1; + bool additional_factor_required = 2; + Factors factors = 3; + VerifyMultiFactorStatus status = 4; +} + +enum VerifyMultiFactorStatus { + DENIED = 0; + SUCESSFULL = 1; +} \ No newline at end of file diff --git a/API/auth.proto b/API/oidc.proto similarity index 99% rename from API/auth.proto rename to API/oidc.proto index 8b0dfa7..d928cbc 100644 --- a/API/auth.proto +++ b/API/oidc.proto @@ -2,7 +2,7 @@ syntax = "proto3"; // schema tags are required for application/x-www-form-urlencoded -package yabslabs.auth.api.v1; +package yabslabs.auth.oidc.api.v1; option go_package = "api"; option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { @@ -23,7 +23,7 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { produces: "application/grpc"; }; -service AuthService { +service OidcService { // OIDC discovery endpoint // provides information about this service diff --git a/API/saml.proto b/API/saml.proto new file mode 100644 index 0000000..90bdb57 --- /dev/null +++ b/API/saml.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; + +// schema tags are required for application/x-www-form-urlencoded + +package yabslabs.auth.saml.api.v1; +option go_package = "api"; + +option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Authorization Service of yabs"; + version: "1.0"; + contact: { + url: "https://github.com/yabslabs/auth" + }; + }; + + schemes: HTTPS; + + consumes: "application/json"; + consumes: "application/grpc"; + + produces: "application/json"; + produces: "application/grpc"; +}; + +service SamlService { + //TODO add SAMl Method +} \ No newline at end of file From 0107929f5d4918b8e679d47ff5d11c7fe24b8626 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 13 Feb 2019 14:49:51 +0100 Subject: [PATCH 8/9] lates changes for review --- API/authn.proto | 82 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/API/authn.proto b/API/authn.proto index 28307ba..a3a6c3d 100644 --- a/API/authn.proto +++ b/API/authn.proto @@ -25,18 +25,18 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { service AuthnService { - // IDP Connection - ///////////////// - rpc AuthNRequest (AuthNRequest) returns (AuthNResponse) { + // With this function a IPD / OP (client) can initiate an interactive authN flow (login) + // Non interactive flow like oauth client_credential need to be handeld directly by the specific implementation + // However they may call the VerifyUserNamePassword function directly + rpc ClientAuthNRequest (ClientAuthNRequest) returns (ClientAuthNResponse) { option (google.api.http) = { - post: "/authn" + post: "/authn/client" body: "*" }; - } - - // Login GUI API - ///////////////// + + //With this call a Client (for example our Login GUI) can check the credentials (username / password) against a datastore + //If sucessfull the call returns wether additional steps like MFA are necessary or, if this step was sufficient rpc VerifyUserNamePassword (VerifyUserNamePasswordRequest) returns (VerifyUserNamePasswordResponse) { option (google.api.http) = { post: "/authn/verify/userpassword" @@ -44,6 +44,17 @@ service AuthnService { }; } + //By clicking a link a user can login in without a need for credentials + //In some cases this is used with an MFA function + rpc VerifyMagicLink(VerifyMagicLinkRequest) returns (VerifyMagicLinkResponse) { + option (google.api.http) = { + post: "/authn/verify/magiclink" + body: "*" + }; + } + + //The Multifactor verfication is responsible for checking the multifactor credential against the configured type + //In some cases this can be used in conjuction with a magic link rpc VerifyMultiFactor (VerifyMultiFactorRequest) returns (VerifyMultiFactorResponse) { option (google.api.http) = { post: "/authn/verify/factors/{id}" @@ -51,19 +62,46 @@ service AuthnService { }; } + //This function is intended to check wether a x509 handshake can be initiaded this may also be used by headless clients / servers + rpc VerifyCertificate (VerifyCertificateRequest) returns (VerifyCertificateResponse) { + option (google.api.http) = { + post: "/authn/verify/certificate" + body: "*" + }; + } +} +// We should return a JWT for validation by the IDP +message AuthNRequest { + string id = 1; //This id is also important for the SSO mapping, refresh tokens and session implementation within the specific providers (idp) + Scopes scopes = 2; + SamlAttributes saml_attributes = 3; + ClientType client_type = 4; +} +//The type of client calling the ClientAuthNRequest function +enum ClientType { + UNKNOWN = 0; + WEB = 1; + OIDC = 2; + SAML = 3; } -message AuthNRequest { - string id = 1; - string scope = 2; +// This message holds the scopes from the call forward by the oidc op +message Scopes { + repeated string = 1; +} + +// This message holds the scopes from the call forward by the saml idp +message SamlAttributes { + repeated string = 1; } +// Returns wether the authN with the user was successfull message AuthNResponse { string id = 1; string scopes = 2; - AuthNStatus auth_n_status = 3; + AuthNStatus auth_n_status = 3; //On sucess we should return a singed JWT, but maybe for somne clients a JSON is enough } enum AuthNStatus { @@ -90,6 +128,23 @@ enum VerifyUserNamePasswordStatus { // We can add hints like password expired here } +message VerifyMagicLinkRequest { + string id = 1; + string key = 2; +} + +message VerifyMagicLinkResponse { + string id = 1; + bool factor_required = 2; + Factors factors = 3; + VerifyMagicLinkStatus verify_magic_link_status= 4; +} + +enum VerifyMagicLinkStatus { + DENIED = 0; + SUCESSFULL = 1; +} + //IMHO this should come from the mgmt API message Factor { string id = 1; @@ -109,6 +164,7 @@ enum FactorType { FBMESSENGER = 3; CTAP1 = 4; //webauthn uf2 keys CTAP2 = 5; //webauthn fido2 keys + RECOVERYKEY = 6; } message VerifyMultiFactorRequest { @@ -119,7 +175,7 @@ message VerifyMultiFactorRequest { message VerifyMultiFactorResponse { string id = 1; bool additional_factor_required = 2; - Factors factors = 3; + Factors factors = 3; //Remaining Factors VerifyMultiFactorStatus status = 4; } From a4de0bbc3e50cdad1d93d6dfa1ea2d1e61dfe868 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 13 Feb 2019 16:51:40 +0100 Subject: [PATCH 9/9] move apis to folder --- {API => api/external}/authn.proto | 0 {API => api/external}/mgmt.proto | 24 ++---------------------- {API => api/external}/oidc.proto | 0 {API => api/external}/saml.proto | 0 api/internal/groups.proto | 0 api/internal/tenants.proto | 0 6 files changed, 2 insertions(+), 22 deletions(-) rename {API => api/external}/authn.proto (100%) rename {API => api/external}/mgmt.proto (94%) rename {API => api/external}/oidc.proto (100%) rename {API => api/external}/saml.proto (100%) create mode 100644 api/internal/groups.proto create mode 100644 api/internal/tenants.proto diff --git a/API/authn.proto b/api/external/authn.proto similarity index 100% rename from API/authn.proto rename to api/external/authn.proto diff --git a/API/mgmt.proto b/api/external/mgmt.proto similarity index 94% rename from API/mgmt.proto rename to api/external/mgmt.proto index 0cac8a8..3dccffa 100644 --- a/API/mgmt.proto +++ b/api/external/mgmt.proto @@ -2,7 +2,7 @@ syntax = "proto3"; import "github.com/yabslabs/yabs/API/core.proto"; -package yabslabs.mgmt.api.v1; +package yabslabs.auth.mgmt.api.v1; option go_package = "api"; option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { @@ -23,7 +23,7 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { produces: "application/grpc"; }; -service AuthService { +service AuthMgmtService { //User rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) { option (google.api.http) = { @@ -131,26 +131,6 @@ service AuthService { delete: "/groups/{group_id}/members/{user_id}" }; } -// Subgroup - rpc AddSubgroupToGroup(AddSubgroupToGroupRequest) returns (AddSubgroupToGroupResponse) { - option (google.api.http) = { - post: "/groups/{group_id}/subgroup/{subgroup_id}" - body: "*" - }; - } - - rpc GetSubgroupFromGroup(GetSubgroupFromGroupRequest) returns (GetSubgroupFromGroupResponse) { - option (google.api.http) = { - post: "/groups/{group_id}/subgroup/{subgroup_id}" - body: "*" - }; - } - - rpc DeleteSubgroupFromGroup(DeleteSubgroupFromGroupRequest) returns (DeleteSubgroupFromGroupResponse) { - option (google.api.http) = { - delete: "/groups/{group_id}/subgroup/{subgroup_id}" - }; - } // Roles rpc GetRoles(google.protobuf.Empty) returns (Roles) { diff --git a/API/oidc.proto b/api/external/oidc.proto similarity index 100% rename from API/oidc.proto rename to api/external/oidc.proto diff --git a/API/saml.proto b/api/external/saml.proto similarity index 100% rename from API/saml.proto rename to api/external/saml.proto diff --git a/api/internal/groups.proto b/api/internal/groups.proto new file mode 100644 index 0000000..e69de29 diff --git a/api/internal/tenants.proto b/api/internal/tenants.proto new file mode 100644 index 0000000..e69de29