github.com/pachyderm/pachyderm@v1.13.4/src/client/admin/v1_10/auth/auth.proto (about)

     1  syntax = "proto3";
     2  
     3  package auth_1_10;
     4  option go_package = "github.com/pachyderm/pachyderm/src/client/admin/v1_10/auth";
     5  
     6  import "gogoproto/gogo.proto";
     7  import "google/protobuf/timestamp.proto";
     8  
     9  /* A note on users
    10   *
    11   * Internally, in Pachyderm, usernames are structured strings. This makes both
    12   * our API and our data model more flexible (at the loss of some type safety).
    13   * Basically, anywhere that Pachyderm internally stores a subject (i.e.
    14   * TokenInfo) or principal (ACL, the 'admins' collection), that username will
    15   * have some structured prefix.
    16   *
    17   * Note that externally-facing principals ({Get,Set}{Scope,ACL}, ModifyAdmins,
    18   * ListAdmins) will have their own conventions
    19   *
    20   * The current user formats are:
    21   * 1) GitHub usernames:
    22   *      "github:MyGitHubUsername"
    23   * 2) Pachyderm robot users:
    24   *      "robot:robot_user_1"
    25   * 3) Pachyderm pipelines:
    26   *      "pipeline:terasort"
    27   */
    28  
    29  //// Activation API
    30  
    31  // ActivateRequest mirrors AuthenticateRequest. The caller is authenticated via
    32  // GitHub OAuth, and then promoted to the cluster's first Admin. Afterwards, the
    33  // caller can promote other users to Admin and remove themselves
    34  message ActivateRequest {
    35    // If set, Pachyderm will authenticate the caller as this user.
    36    // - If set to a github user (i.e. it has a 'github:' prefix or no prefix)
    37    //   then Pachyderm will confirm that it matches the user associated with
    38    //   'github_token'
    39    // - If set to a robot user (i.e. it has a 'robot:' prefix), then Pachyderm
    40    //   will generate a new token for the robot user; this token will be the only
    41    //   way to administer this cluster until more admins are added.
    42    string subject = 2;
    43  
    44    // This is the token returned by GitHub and used to authenticate the caller.
    45    // When Pachyderm is deployed locally, setting this value to a given string
    46    // will automatically authenticate the caller as a GitHub user whose username
    47    // is that string (unless this "looks like" a GitHub access code, in which
    48    // case Pachyderm does retrieve the corresponding GitHub username)
    49    string github_token = 1 [(gogoproto.customname) = "GitHubToken"];
    50  }
    51  
    52  message ActivateResponse {
    53    // pach_token authenticates the caller with Pachyderm (if you want to perform
    54    // Pachyderm operations after auth has been activated as themselves, you must
    55    // present this token along with your regular request)
    56    string pach_token = 1;
    57  }
    58  
    59  message DeactivateRequest {}
    60  message DeactivateResponse {}
    61  
    62  // IDProvider configures a single ID provider that can authenticate Pachyderm
    63  // users
    64  message IDProvider {
    65    // Name identifies this authentication backend in Pachyderm.
    66    string name = 1;
    67  
    68    // Description is a human-readable description of this authentication
    69    // backend. It's ignored by Pachyderm, but exists for the benefit of users
    70    // configuring Pachyderm's auth system.
    71    string description = 2;
    72  
    73    // SAMLOptions describes a SAML-based identity provider
    74    message SAMLOptions {
    75      // metadata_url is the URL of the SAML ID provider's metadata service
    76      // (which Pachd can query to get more info about the SAML ID provider)
    77      string metadata_url = 1 [(gogoproto.customname) = "MetadataURL"];
    78  
    79      // metadata_xml is a direct reproduction of the ID provider's metadata.
    80      // Users can set this field in the argument to SetConfig if the ID provider
    81      // can't be reached from pachd (e.g. because it's on a separate network to
    82      // which Pachyderm users also have access) or for testing.  Exactly one of
    83      // metadata_url and metadata_xml should be set in calls to SetConfig, but
    84      // internally, if metadata_url is set, the result of scraping the metadata
    85      // URL will be placed here in the result from GetConfig().
    86      bytes metadata_xml = 2 [(gogoproto.customname) = "MetadataXML"];
    87  
    88      // If this ID provider supports sending group memberships via attribute,
    89      // then users can set group_attribute to the SAML attribute that indicates
    90      // group mmbership, and Pachyderm will update users' group memberships when
    91      // they authenticate.
    92      string group_attribute = 3;
    93    }
    94    SAMLOptions saml = 3 [(gogoproto.customname) = "SAML"];
    95  
    96    // GitHubOptions is an empty protobuf message whose presence in the IDProvider
    97    // of an AuthConfig indicates that GitHub auth should be enabled.
    98    message GitHubOptions{}
    99    GitHubOptions github = 4 [(gogoproto.customname) = "GitHub"];
   100  }
   101  
   102  // Configure Pachyderm's auth system (particularly authentication backends
   103  message AuthConfig {
   104    // live_config_version identifies the version of a given pachyderm cluster's
   105    // current auth configuration; if a user tries to write an auth configuration
   106    // where live_config_version doesn't match the version of the cluster's
   107    // current config, the write will fail. This allows for safe
   108    // read+modify+write config changes.
   109    int64 live_config_version = 1;
   110  
   111    // id_providers describes external ID providers that can authenticate
   112    // Pachyderm users (e.g. GitHub, Okta, etc)
   113    repeated IDProvider id_providers = 2 [(gogoproto.customname) = "IDProviders"];
   114  
   115    // saml_svc_options configures the SAML services (Assertion Consumer Service
   116    // and Metadata Service) that Pachd can export.
   117    message SAMLServiceOptions {
   118      // acs is the URL of Pachd's Assertion Consumer Service (i.e. where SAML ID
   119      // providers can send SAMLResponses to Pachd). If Pachyderm is running in a
   120      // private cluster, the cluster admin would be responsible for setting up a
   121      // domain name/proxy to resolve to pachd:654/acs
   122      string acs_url = 1 [(gogoproto.customname) = "ACSURL"];
   123  
   124      // metadata_url is the public URL of Pachd's SAML metadata service (some
   125      // SAML ID providers will query this for information about Pachyderm's SAML
   126      // implementation and use it to idenfity Pachyderm as a service provider).
   127      // If Pachyderm is running in a private cluster, the cluster admin would be
   128      // responsible for creating this URL (which must resolve to
   129      // pachd:654/saml/metadata)
   130      string metadata_url = 2 [(gogoproto.customname) = "MetadataURL"];
   131  
   132      // dash_url is the public address of this cluster's Pachyderm
   133      // dashboard, if one exists; this option determines where users will be
   134      // redirected after successfully authenticating
   135      string dash_url = 3 [(gogoproto.customname) = "DashURL"];
   136  
   137      // session_duration determines the duration of SAML-IdP-authenticated user
   138      // sessions (specified as a Golang time duration, e.g. "24h" or "600m"). If
   139      // unset, user sessions last 24 hours (a short default, as SAML assertions
   140      // may contain group memberships that need to be refreshed)
   141      string session_duration = 4;
   142  
   143      // debug_logging determines whether pachd emits verbose logs (including
   144      // SAML credentials) as it receives them, which may be helpful for
   145      // debugging. This will probably not be present in any official releases.
   146      bool debug_logging = 5;
   147    }
   148    SAMLServiceOptions saml_svc_options = 3 [(gogoproto.customname) = "SAMLServiceOptions"];
   149  }
   150  
   151  message GetConfigurationRequest {}
   152  message GetConfigurationResponse {
   153    AuthConfig configuration = 1;
   154  }
   155  message SetConfigurationRequest {
   156    AuthConfig configuration = 1;
   157  }
   158  message SetConfigurationResponse {}
   159  
   160  // Get the current list of cluster admins
   161  message GetAdminsRequest{}
   162  message GetAdminsResponse{
   163    // admins contains the list of cluster admins
   164    repeated string admins = 1;
   165  }
   166  
   167  // Add or remove cluster admins
   168  message ModifyAdminsRequest {
   169    repeated string add = 1;
   170    repeated string remove = 2;
   171  }
   172  message ModifyAdminsResponse {}
   173  
   174  //// Authentication data structures
   175  
   176  // OTPInfo is the analogue of 'TokenInfo' for Authentication Codes (short-lived,
   177  // one-time-use codes that are passed to the frontend and then exchanged for
   178  // longer-lived tokens)
   179  message OTPInfo {
   180    // Subject (i.e. Pachyderm account) that a given OTP authenticates. This may
   181    // be copied into the 'subject' field of a TokenInfo, and therefore has the
   182    // same format, with the same prefixes.
   183    string subject = 1;
   184  
   185    // session_expiration indicates when the subject's session expires, a.k.a.
   186    // when the Token to which this OTP converts expires (likely later than this
   187    // OTP expires, but never earlier).
   188    google.protobuf.Timestamp session_expiration = 2;
   189  }
   190  
   191  // TokenInfo is the 'value' of an auth token 'key' in the 'tokens' collection
   192  message TokenInfo {
   193    // Subject (i.e. Pachyderm account) that a given token authorizes. Prefixed
   194    // with "github:" or "robot:" to distinguish the two classes of
   195    // Subject in Pachyderm
   196    string subject = 1;
   197  
   198    enum TokenSource {
   199      INVALID = 0;
   200      AUTHENTICATE = 1; // returned by Authenticate()--non-revokeable
   201      GET_TOKEN = 2;  // returned by GetToken()--revokeable.
   202    }
   203    TokenSource source = 2;
   204  }
   205  
   206  //// Authentication API
   207  
   208  message AuthenticateRequest {
   209    // Exactly one of 'github_token' or 'one_time_password' must be set:
   210  
   211    // This is the token returned by GitHub and used to authenticate the caller.
   212    // When Pachyderm is deployed locally, setting this value to a given string
   213    // will automatically authenticate the caller as a GitHub user whose username
   214    // is that string (unless this "looks like" a GitHub access code, in which
   215    // case Pachyderm does retrieve the corresponding GitHub username)
   216    string github_token = 1 [(gogoproto.customname) = "GitHubToken"];
   217  
   218    // This is a short-lived, one-time-use password generated by Pachyderm, for
   219    // the purpose of propagating authentication to new clients (e.g. from the
   220    // dash to pachd)
   221    string one_time_password = 2;
   222  }
   223  
   224  message AuthenticateResponse {
   225    // pach_token authenticates the caller with Pachyderm (if you want to perform
   226    // Pachyderm operations after auth has been activated as themselves, you must
   227    // present this token along with your regular request)
   228    string pach_token = 1;
   229  }
   230  
   231  message WhoAmIRequest {}
   232  
   233  message WhoAmIResponse {
   234    string username = 1;
   235    bool is_admin = 2;
   236    int64 ttl = 3 [(gogoproto.customname) = "TTL"];
   237  }
   238  
   239  //// Authorization data structures
   240  
   241  // Scope (actually a "role" in canonical security nomenclature) represents a
   242  // rough level of access that a principal has to a repo
   243  enum Scope {
   244    // To remove a user's scope from a repo, set their scope to NONE
   245    NONE = 0;
   246    READER = 1;
   247    WRITER = 2;
   248    OWNER = 3;
   249  }
   250  
   251  message ACL {
   252    // principal -> scope. All principals are the default principal of a Pachyderm
   253    // subject (i.e. all keys in this map are strings prefixed with either
   254    // "github:" or "robot:", followed by the name of a GitHub user, all of whom
   255    // are Pachyderm subjects, or a Pachyderm robot user)
   256    map<string, Scope> entries = 1;
   257  }
   258  
   259  message Users {
   260    map<string, bool> usernames = 1;
   261  }
   262  
   263  message Groups {
   264    map<string, bool> groups = 1;
   265  }
   266  
   267  //// Authorization API
   268  
   269  message AuthorizeRequest {
   270    // repo is the object that the caller wants to access
   271    string repo = 1;
   272  
   273    // scope is the access level that the caller needs to perform an action
   274    Scope scope = 2;
   275  }
   276  
   277  message AuthorizeResponse {
   278    // authorized is true if the caller has at least
   279    // 'AuthorizeRequest.scope'-level access to 'AuthorizeRequest.repo', and false
   280    // otherwise
   281    bool authorized = 1;
   282  }
   283  
   284  message GetScopeRequest {
   285    // username is the principal (some of which belong to robots rather than
   286    // users, but the name is preserved for now to provide compatibility with the
   287    // pachyderm dash) whose access level is queried. To query the access level
   288    // of a robot user, the caller must prefix username with "robot:". If
   289    // 'username' has no prefix (i.e. no ":"), then it's assumed to be a github
   290    // user's principal.
   291    string username = 1;
   292  
   293    // repos are the objects to which 'username's access level is being queried
   294    repeated string repos = 2;
   295  }
   296  
   297  message GetScopeResponse {
   298    // scopes (actually a "role"--see "Scope") are the access level that
   299    // 'GetScopeRequest.username' has to each repo in 'GetScopeRequest.repos', in
   300    // the same order that repos appeared in 'repos'.
   301    repeated Scope scopes = 1;
   302  }
   303  
   304  message SetScopeRequest {
   305    // username is the principal (some of which belong to robots rather than
   306    // users, but the name is preserved for now to provide compatibility with the
   307    // pachyderm dash) whose access is being granted/revoked. As with
   308    // GetScopeRequest, to set the access level of a robot user, the caller must
   309    // prefix username with "robot:". If 'username' has no prefix (i.e. no ":"),
   310    // then it's assumed to be a github user's principal.
   311    string username = 1;
   312  
   313    // repo is the object to which access is being granted/revoked
   314    string repo = 2;
   315  
   316    // scope (actually a "role"--see "Scope") is the access level that the owner
   317    // of 'principal' will now have
   318    Scope scope = 3;
   319  }
   320  
   321  message SetScopeResponse {}
   322  
   323  message GetACLRequest {
   324    string repo = 1;
   325  }
   326  
   327  message ACLEntry {
   328    // username is the principal posessing this level of access to this ACL's
   329    // repo (despite the name, this principal may be for a human github user or a
   330    // pachyderm robot)
   331    string username = 1;
   332  
   333    // scope is the level of access that the owner of 'principal' has to this
   334    // ACL's repo (actually a role in typical security terminology)
   335    Scope scope = 2;
   336  }
   337  
   338  // GetACLReponse contains the list of entries on a Pachyderm ACL.
   339  //
   340  // To avoid migration pain with the Pachyderm dash the list of user principal
   341  // entries and robot principal entries are separate. This way, no prefix or
   342  // other disambiguating device is needed in 'entries' to separate user
   343  // principals from robot principals (which would confuse the dash). Instead,
   344  // the dash can simply ignore robot principals.
   345  message GetACLResponse {
   346    // entries contains all [user principal] -> [role] mappings. This is separate
   347    // from robot_entries to avoid migration pain the Pachyderm dashboard
   348    repeated ACLEntry entries = 1;
   349  
   350    // robot_entries contains all [robot principal] -> [role] mappings. This is
   351    // separate from entries to be unambiguous (all keys are robot principals, but
   352    // have no prefixes) while avoiding migration pain in the Pachyderm dashboard.
   353    repeated ACLEntry robot_entries = 2;
   354  }
   355  
   356  message SetACLRequest {
   357    string repo = 1;
   358    repeated ACLEntry entries = 2;
   359  }
   360  
   361  message SetACLResponse {}
   362  
   363  //// Token API (very limited -- for pipelines)
   364  
   365  message GetAuthTokenRequest {
   366    // The returned token will allow the caller to access resources as this
   367    // subject
   368    string subject = 1;
   369  
   370    // ttl indicates the requested (approximate) remaining lifetime of this token,
   371    // in seconds
   372    int64 ttl = 2 [(gogoproto.customname) = "TTL"];
   373  }
   374  
   375  message GetAuthTokenResponse {
   376    // A canonicalized version of the subject in the request
   377    string subject = 2;
   378  
   379    // A new auth token for the user in 'GetAuthTokenRequest.Subject' token
   380    string token = 1;
   381  }
   382  
   383  message ExtendAuthTokenRequest {
   384    // token indicates the Pachyderm token whose TTL is being extended
   385    string token = 1;
   386  
   387    // ttl indicates the new TTL of 'token' (if it's longer than the existing TTL)
   388    int64 ttl = 2 [(gogoproto.customname) = "TTL"];
   389  }
   390  
   391  message ExtendAuthTokenResponse {}
   392  
   393  message RevokeAuthTokenRequest {
   394    string token = 1;
   395  }
   396  
   397  message RevokeAuthTokenResponse {}
   398  
   399  message SetGroupsForUserRequest {
   400    string username = 1;
   401    repeated string groups = 2;
   402  }
   403  
   404  message SetGroupsForUserResponse {}
   405  
   406  message ModifyMembersRequest {
   407    string group = 1;
   408    repeated string add = 2;
   409    repeated string remove = 3;
   410  }
   411  
   412  message ModifyMembersResponse {}
   413  
   414  message GetGroupsRequest {
   415    string username = 1;
   416  }
   417  
   418  message GetGroupsResponse {
   419    repeated string groups = 1;
   420  }
   421  
   422  message GetUsersRequest {
   423    string group = 1;
   424  }
   425  
   426  message GetUsersResponse {
   427    repeated string usernames = 1;
   428  }
   429  
   430  // GetOneTimePassword allows users to generate short-lived (~30s) tokens that
   431  // can be passed to Authenticate() (via AuthenticateRequest.one_time_password)
   432  // and exchanged for a longer-lived pachyderm token. This is more secure than
   433  // GetAuthToken, which produces long-lived authorization tokens.
   434  message GetOneTimePasswordRequest {
   435    // If the caller is an admin, GetOneTimePassword() can return a code for
   436    // any user (useful for testing).
   437    // If the caller is not an admin, GetOneTimePassword() will return an
   438    // authentication code for the caller if username is unset or set to the
   439    // caller's username (and will return an error otherwise)
   440    string subject = 1;
   441  
   442    // ttl indicates the requested (approximate) remaining lifetime of this token,
   443    // in seconds
   444    int64 ttl = 2 [(gogoproto.customname) = "TTL"];
   445  }
   446  
   447  message GetOneTimePasswordResponse {
   448    // 'code' is the string that must be presented in
   449    // AuthenticateRequest.one_time_password to login as
   450    // GetOneTimePasswordRequest.subject
   451    string code = 1;
   452  
   453    // expiration is the time at which the token in 'code' will expire
   454    google.protobuf.Timestamp otp_expiration = 2 [(gogoproto.customname) = "OTPExpiration"];
   455  }
   456  
   457  service API {
   458    // Activate/Deactivate the auth API. 'Activate' sets an initial set of admins
   459    // for the Pachyderm cluster, and 'Deactivate' removes all ACLs, tokens, and
   460    // admins from the Pachyderm cluster, making all data publicly accessable
   461    rpc Activate(ActivateRequest) returns (ActivateResponse) {}
   462    rpc Deactivate(DeactivateRequest) returns (DeactivateResponse) {}
   463  
   464    rpc GetConfiguration(GetConfigurationRequest) returns (GetConfigurationResponse) {}
   465    rpc SetConfiguration(SetConfigurationRequest) returns (SetConfigurationResponse) {}
   466  
   467    // GetAdmins returns the current list of cluster admins
   468    rpc GetAdmins(GetAdminsRequest) returns (GetAdminsResponse) {}
   469    // ModifyAdmins adds or removes admins from the cluster
   470    rpc ModifyAdmins(ModifyAdminsRequest) returns (ModifyAdminsResponse) {}
   471  
   472    rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {}
   473    rpc Authorize(AuthorizeRequest) returns (AuthorizeResponse) {}
   474    rpc WhoAmI(WhoAmIRequest) returns (WhoAmIResponse) {}
   475  
   476    rpc GetScope(GetScopeRequest) returns (GetScopeResponse) {}
   477    rpc SetScope(SetScopeRequest) returns (SetScopeResponse) {}
   478    rpc GetACL(GetACLRequest) returns (GetACLResponse) {}
   479    rpc SetACL(SetACLRequest) returns (SetACLResponse) {}
   480  
   481    rpc GetAuthToken(GetAuthTokenRequest) returns (GetAuthTokenResponse) {}
   482    rpc ExtendAuthToken(ExtendAuthTokenRequest) returns (ExtendAuthTokenResponse) {}
   483    rpc RevokeAuthToken(RevokeAuthTokenRequest) returns (RevokeAuthTokenResponse) {}
   484  
   485    rpc SetGroupsForUser(SetGroupsForUserRequest) returns (SetGroupsForUserResponse) {}
   486    rpc ModifyMembers(ModifyMembersRequest) returns (ModifyMembersResponse) {}
   487    rpc GetGroups(GetGroupsRequest) returns (GetGroupsResponse) {}
   488    rpc GetUsers(GetUsersRequest) returns (GetUsersResponse) {}
   489  
   490    rpc GetOneTimePassword(GetOneTimePasswordRequest) returns (GetOneTimePasswordResponse) {}
   491  }