- Add auth/login and auth/logout to mciasgrpcctl, calling the existing AuthService.Login/Logout RPCs; password is always prompted interactively (term.ReadPassword), never accepted as a flag, raw bytes zeroed after use - Add proto/mcias/v1/policy.proto with PolicyService (List, Create, Get, Update, Delete policy rules) - Regenerate gen/mcias/v1/ stubs to include policy - Implement internal/grpcserver/policyservice.go delegating to the same db layer as the REST policy handlers - Register PolicyService in grpcserver.go - Add policy list/create/get/update/delete to mciasgrpcctl - Update mciasgrpcctl man page with new commands Security: auth login uses the same interactive password prompt pattern as mciasctl; password never appears in process args, shell history, or logs; raw bytes zeroed after string conversion (same as REST CLI and REST server). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
412 lines
13 KiB
Go
412 lines
13 KiB
Go
// TokenService: token validation, service-token issuance, and revocation.
|
|
|
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
// versions:
|
|
// protoc-gen-go v1.36.11
|
|
// protoc v3.20.3
|
|
// source: mcias/v1/token.proto
|
|
|
|
package mciasv1
|
|
|
|
import (
|
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
|
reflect "reflect"
|
|
sync "sync"
|
|
unsafe "unsafe"
|
|
)
|
|
|
|
const (
|
|
// Verify that this generated code is sufficiently up-to-date.
|
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
)
|
|
|
|
// ValidateTokenRequest carries the token to validate.
|
|
// The token may also be supplied via the Authorization metadata key;
|
|
// this field is an alternative for callers that cannot set metadata.
|
|
type ValidateTokenRequest struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *ValidateTokenRequest) Reset() {
|
|
*x = ValidateTokenRequest{}
|
|
mi := &file_mcias_v1_token_proto_msgTypes[0]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *ValidateTokenRequest) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*ValidateTokenRequest) ProtoMessage() {}
|
|
|
|
func (x *ValidateTokenRequest) ProtoReflect() protoreflect.Message {
|
|
mi := &file_mcias_v1_token_proto_msgTypes[0]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use ValidateTokenRequest.ProtoReflect.Descriptor instead.
|
|
func (*ValidateTokenRequest) Descriptor() ([]byte, []int) {
|
|
return file_mcias_v1_token_proto_rawDescGZIP(), []int{0}
|
|
}
|
|
|
|
func (x *ValidateTokenRequest) GetToken() string {
|
|
if x != nil {
|
|
return x.Token
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// ValidateTokenResponse reports validity and, on success, the claims.
|
|
type ValidateTokenResponse struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Valid bool `protobuf:"varint,1,opt,name=valid,proto3" json:"valid,omitempty"`
|
|
Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` // UUID of the account; empty if invalid
|
|
Roles []string `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty"`
|
|
ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *ValidateTokenResponse) Reset() {
|
|
*x = ValidateTokenResponse{}
|
|
mi := &file_mcias_v1_token_proto_msgTypes[1]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *ValidateTokenResponse) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*ValidateTokenResponse) ProtoMessage() {}
|
|
|
|
func (x *ValidateTokenResponse) ProtoReflect() protoreflect.Message {
|
|
mi := &file_mcias_v1_token_proto_msgTypes[1]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use ValidateTokenResponse.ProtoReflect.Descriptor instead.
|
|
func (*ValidateTokenResponse) Descriptor() ([]byte, []int) {
|
|
return file_mcias_v1_token_proto_rawDescGZIP(), []int{1}
|
|
}
|
|
|
|
func (x *ValidateTokenResponse) GetValid() bool {
|
|
if x != nil {
|
|
return x.Valid
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (x *ValidateTokenResponse) GetSubject() string {
|
|
if x != nil {
|
|
return x.Subject
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *ValidateTokenResponse) GetRoles() []string {
|
|
if x != nil {
|
|
return x.Roles
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *ValidateTokenResponse) GetExpiresAt() *timestamppb.Timestamp {
|
|
if x != nil {
|
|
return x.ExpiresAt
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IssueServiceTokenRequest specifies the system account to issue a token for.
|
|
type IssueServiceTokenRequest struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
AccountId string `protobuf:"bytes,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` // UUID of the system account
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *IssueServiceTokenRequest) Reset() {
|
|
*x = IssueServiceTokenRequest{}
|
|
mi := &file_mcias_v1_token_proto_msgTypes[2]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *IssueServiceTokenRequest) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*IssueServiceTokenRequest) ProtoMessage() {}
|
|
|
|
func (x *IssueServiceTokenRequest) ProtoReflect() protoreflect.Message {
|
|
mi := &file_mcias_v1_token_proto_msgTypes[2]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use IssueServiceTokenRequest.ProtoReflect.Descriptor instead.
|
|
func (*IssueServiceTokenRequest) Descriptor() ([]byte, []int) {
|
|
return file_mcias_v1_token_proto_rawDescGZIP(), []int{2}
|
|
}
|
|
|
|
func (x *IssueServiceTokenRequest) GetAccountId() string {
|
|
if x != nil {
|
|
return x.AccountId
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// IssueServiceTokenResponse returns the new token and its expiry.
|
|
type IssueServiceTokenResponse struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
|
ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *IssueServiceTokenResponse) Reset() {
|
|
*x = IssueServiceTokenResponse{}
|
|
mi := &file_mcias_v1_token_proto_msgTypes[3]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *IssueServiceTokenResponse) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*IssueServiceTokenResponse) ProtoMessage() {}
|
|
|
|
func (x *IssueServiceTokenResponse) ProtoReflect() protoreflect.Message {
|
|
mi := &file_mcias_v1_token_proto_msgTypes[3]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use IssueServiceTokenResponse.ProtoReflect.Descriptor instead.
|
|
func (*IssueServiceTokenResponse) Descriptor() ([]byte, []int) {
|
|
return file_mcias_v1_token_proto_rawDescGZIP(), []int{3}
|
|
}
|
|
|
|
func (x *IssueServiceTokenResponse) GetToken() string {
|
|
if x != nil {
|
|
return x.Token
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (x *IssueServiceTokenResponse) GetExpiresAt() *timestamppb.Timestamp {
|
|
if x != nil {
|
|
return x.ExpiresAt
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RevokeTokenRequest specifies the JTI to revoke.
|
|
type RevokeTokenRequest struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
Jti string `protobuf:"bytes,1,opt,name=jti,proto3" json:"jti,omitempty"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *RevokeTokenRequest) Reset() {
|
|
*x = RevokeTokenRequest{}
|
|
mi := &file_mcias_v1_token_proto_msgTypes[4]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *RevokeTokenRequest) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*RevokeTokenRequest) ProtoMessage() {}
|
|
|
|
func (x *RevokeTokenRequest) ProtoReflect() protoreflect.Message {
|
|
mi := &file_mcias_v1_token_proto_msgTypes[4]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use RevokeTokenRequest.ProtoReflect.Descriptor instead.
|
|
func (*RevokeTokenRequest) Descriptor() ([]byte, []int) {
|
|
return file_mcias_v1_token_proto_rawDescGZIP(), []int{4}
|
|
}
|
|
|
|
func (x *RevokeTokenRequest) GetJti() string {
|
|
if x != nil {
|
|
return x.Jti
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// RevokeTokenResponse confirms revocation.
|
|
type RevokeTokenResponse struct {
|
|
state protoimpl.MessageState `protogen:"open.v1"`
|
|
unknownFields protoimpl.UnknownFields
|
|
sizeCache protoimpl.SizeCache
|
|
}
|
|
|
|
func (x *RevokeTokenResponse) Reset() {
|
|
*x = RevokeTokenResponse{}
|
|
mi := &file_mcias_v1_token_proto_msgTypes[5]
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
|
|
func (x *RevokeTokenResponse) String() string {
|
|
return protoimpl.X.MessageStringOf(x)
|
|
}
|
|
|
|
func (*RevokeTokenResponse) ProtoMessage() {}
|
|
|
|
func (x *RevokeTokenResponse) ProtoReflect() protoreflect.Message {
|
|
mi := &file_mcias_v1_token_proto_msgTypes[5]
|
|
if x != nil {
|
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
if ms.LoadMessageInfo() == nil {
|
|
ms.StoreMessageInfo(mi)
|
|
}
|
|
return ms
|
|
}
|
|
return mi.MessageOf(x)
|
|
}
|
|
|
|
// Deprecated: Use RevokeTokenResponse.ProtoReflect.Descriptor instead.
|
|
func (*RevokeTokenResponse) Descriptor() ([]byte, []int) {
|
|
return file_mcias_v1_token_proto_rawDescGZIP(), []int{5}
|
|
}
|
|
|
|
var File_mcias_v1_token_proto protoreflect.FileDescriptor
|
|
|
|
const file_mcias_v1_token_proto_rawDesc = "" +
|
|
"\n" +
|
|
"\x14mcias/v1/token.proto\x12\bmcias.v1\x1a\x1fgoogle/protobuf/timestamp.proto\",\n" +
|
|
"\x14ValidateTokenRequest\x12\x14\n" +
|
|
"\x05token\x18\x01 \x01(\tR\x05token\"\x98\x01\n" +
|
|
"\x15ValidateTokenResponse\x12\x14\n" +
|
|
"\x05valid\x18\x01 \x01(\bR\x05valid\x12\x18\n" +
|
|
"\asubject\x18\x02 \x01(\tR\asubject\x12\x14\n" +
|
|
"\x05roles\x18\x03 \x03(\tR\x05roles\x129\n" +
|
|
"\n" +
|
|
"expires_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\"9\n" +
|
|
"\x18IssueServiceTokenRequest\x12\x1d\n" +
|
|
"\n" +
|
|
"account_id\x18\x01 \x01(\tR\taccountId\"l\n" +
|
|
"\x19IssueServiceTokenResponse\x12\x14\n" +
|
|
"\x05token\x18\x01 \x01(\tR\x05token\x129\n" +
|
|
"\n" +
|
|
"expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\"&\n" +
|
|
"\x12RevokeTokenRequest\x12\x10\n" +
|
|
"\x03jti\x18\x01 \x01(\tR\x03jti\"\x15\n" +
|
|
"\x13RevokeTokenResponse2\x8a\x02\n" +
|
|
"\fTokenService\x12P\n" +
|
|
"\rValidateToken\x12\x1e.mcias.v1.ValidateTokenRequest\x1a\x1f.mcias.v1.ValidateTokenResponse\x12\\\n" +
|
|
"\x11IssueServiceToken\x12\".mcias.v1.IssueServiceTokenRequest\x1a#.mcias.v1.IssueServiceTokenResponse\x12J\n" +
|
|
"\vRevokeToken\x12\x1c.mcias.v1.RevokeTokenRequest\x1a\x1d.mcias.v1.RevokeTokenResponseB2Z0git.wntrmute.dev/kyle/mcias/gen/mcias/v1;mciasv1b\x06proto3"
|
|
|
|
var (
|
|
file_mcias_v1_token_proto_rawDescOnce sync.Once
|
|
file_mcias_v1_token_proto_rawDescData []byte
|
|
)
|
|
|
|
func file_mcias_v1_token_proto_rawDescGZIP() []byte {
|
|
file_mcias_v1_token_proto_rawDescOnce.Do(func() {
|
|
file_mcias_v1_token_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mcias_v1_token_proto_rawDesc), len(file_mcias_v1_token_proto_rawDesc)))
|
|
})
|
|
return file_mcias_v1_token_proto_rawDescData
|
|
}
|
|
|
|
var file_mcias_v1_token_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
|
var file_mcias_v1_token_proto_goTypes = []any{
|
|
(*ValidateTokenRequest)(nil), // 0: mcias.v1.ValidateTokenRequest
|
|
(*ValidateTokenResponse)(nil), // 1: mcias.v1.ValidateTokenResponse
|
|
(*IssueServiceTokenRequest)(nil), // 2: mcias.v1.IssueServiceTokenRequest
|
|
(*IssueServiceTokenResponse)(nil), // 3: mcias.v1.IssueServiceTokenResponse
|
|
(*RevokeTokenRequest)(nil), // 4: mcias.v1.RevokeTokenRequest
|
|
(*RevokeTokenResponse)(nil), // 5: mcias.v1.RevokeTokenResponse
|
|
(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
|
|
}
|
|
var file_mcias_v1_token_proto_depIdxs = []int32{
|
|
6, // 0: mcias.v1.ValidateTokenResponse.expires_at:type_name -> google.protobuf.Timestamp
|
|
6, // 1: mcias.v1.IssueServiceTokenResponse.expires_at:type_name -> google.protobuf.Timestamp
|
|
0, // 2: mcias.v1.TokenService.ValidateToken:input_type -> mcias.v1.ValidateTokenRequest
|
|
2, // 3: mcias.v1.TokenService.IssueServiceToken:input_type -> mcias.v1.IssueServiceTokenRequest
|
|
4, // 4: mcias.v1.TokenService.RevokeToken:input_type -> mcias.v1.RevokeTokenRequest
|
|
1, // 5: mcias.v1.TokenService.ValidateToken:output_type -> mcias.v1.ValidateTokenResponse
|
|
3, // 6: mcias.v1.TokenService.IssueServiceToken:output_type -> mcias.v1.IssueServiceTokenResponse
|
|
5, // 7: mcias.v1.TokenService.RevokeToken:output_type -> mcias.v1.RevokeTokenResponse
|
|
5, // [5:8] is the sub-list for method output_type
|
|
2, // [2:5] is the sub-list for method input_type
|
|
2, // [2:2] is the sub-list for extension type_name
|
|
2, // [2:2] is the sub-list for extension extendee
|
|
0, // [0:2] is the sub-list for field type_name
|
|
}
|
|
|
|
func init() { file_mcias_v1_token_proto_init() }
|
|
func file_mcias_v1_token_proto_init() {
|
|
if File_mcias_v1_token_proto != nil {
|
|
return
|
|
}
|
|
type x struct{}
|
|
out := protoimpl.TypeBuilder{
|
|
File: protoimpl.DescBuilder{
|
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mcias_v1_token_proto_rawDesc), len(file_mcias_v1_token_proto_rawDesc)),
|
|
NumEnums: 0,
|
|
NumMessages: 6,
|
|
NumExtensions: 0,
|
|
NumServices: 1,
|
|
},
|
|
GoTypes: file_mcias_v1_token_proto_goTypes,
|
|
DependencyIndexes: file_mcias_v1_token_proto_depIdxs,
|
|
MessageInfos: file_mcias_v1_token_proto_msgTypes,
|
|
}.Build()
|
|
File_mcias_v1_token_proto = out.File
|
|
file_mcias_v1_token_proto_goTypes = nil
|
|
file_mcias_v1_token_proto_depIdxs = nil
|
|
}
|