Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5081,6 +5081,8 @@ message PluginSpecV1 {
PluginOpenAISettings openai = 3;
// Settings for the Okta plugin
PluginOktaSettings okta = 4;
// Settings for device trust jamf plugin
PluginJamfSettings jamf = 5;
}
}

Expand Down Expand Up @@ -5108,6 +5110,13 @@ message PluginOpenAISettings {
option (gogoproto.equal) = true;
}

// Defines settings for Jamf plugin.
message PluginJamfSettings {
option (gogoproto.equal) = true;
// Jamf service spec
JamfSpecV1 jamf_spec = 1;
}

// Defines settings for the Okta plugin.
message PluginOktaSettings {
option (gogoproto.equal) = true;
Expand All @@ -5120,9 +5129,16 @@ message PluginBootstrapCredentialsV1 {
oneof credentials {
PluginOAuth2AuthorizationCodeCredentials oauth2_authorization_code = 1;
PluginBearerTokenCredentials bearer_token = 2;
PluginIdSecretCredential id_secret = 3;
}
}

// PluginIdSecretCredential can be OAuth2-like client_id and client_secret or username and password.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what cases will we accept OAuth2 client_id and client_secret from the user? Will this be how we handle Mattermost etc., where we can not have one predefined Client ID, owned by us?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self hosted Mattermost was in mind when I wrote that comment. But basically I tried to make this as generic as possible where we can recevice clientID:clientSecet, apiKey:apiToken, uname:pass.

message PluginIdSecretCredential {
string id = 1;
string secret = 2;
}

message PluginOAuth2AuthorizationCodeCredentials {
string authorization_code = 1;
string redirect_uri = 2;
Expand Down Expand Up @@ -5155,6 +5171,7 @@ message PluginCredentialsV1 {
oneof credentials {
PluginOAuth2AccessTokenCredentials oauth2_access_token = 1;
PluginBearerTokenCredentials bearer_token = 2;
PluginIdSecretCredential id_secret = 3;
}
}

Expand Down Expand Up @@ -5612,6 +5629,7 @@ message ServerInfoSpecV1 {

// JamfSpecV1 is the base configuration for the Jamf MDM service.
message JamfSpecV1 {
option (gogoproto.equal) = true;
// Enabled toggles the service on or off.
bool enabled = 1 [(gogoproto.jsontag) = "enabled,omitempty"];
// Name of the service device source.
Expand Down Expand Up @@ -5646,6 +5664,7 @@ message JamfSpecV1 {

// JamfInventoryEntry is an inventory sync entry for [JamfSpecV1].
message JamfInventoryEntry {
option (gogoproto.equal) = true;
// Jamf Pro API RSQL filter, used when querying endpoints like
// "/api/v1/computers-inventory".
// See https://developer.jamf.com/jamf-pro/reference/get_v1-computers-inventory.
Expand Down
26 changes: 26 additions & 0 deletions api/types/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ const (
PluginTypeOpenAI = "openai"
// PluginTypeOkta is the Okta plugin
PluginTypeOkta = "okta"
// PluginTypeJamf is the Jamf MDM plugin
PluginTypeJamf = "jamf"
)

// PluginSubkind represents the type of the plugin, e.g., access request, MDM etc.
type PluginSubkind string

const (
// PluginSubkindUnknown is returned when no plugin subkind matches.
PluginSubkindUnknown PluginSubkind = ""
// PluginSubkindMDM represents MDM plugins collectively
PluginSubkindMDM = "mdm"
// PluginSubkindAccess represents access request plugins collectively
PluginSubkindAccess = "access"
)

// Plugin represents a plugin instance
Expand Down Expand Up @@ -113,6 +127,16 @@ func (p *PluginV1) CheckAndSetDefaults() error {
if (bearer.Token == "") == (bearer.TokenFile == "") {
return trace.BadParameter("exactly one of Token and TokenFile must be specified")
}
case *PluginSpecV1_Jamf:
if settings.Jamf.JamfSpec.ApiEndpoint == "" {
return trace.BadParameter("api endpoint must be set")
}
if p.Credentials == nil {
return trace.BadParameter("credentials must be set")
}
if p.Credentials.GetIdSecret().Id == "" || p.Credentials.GetIdSecret().Secret == "" {
return trace.BadParameter("Jamf plugin requires Jamf account username and password")
Comment thread
flyinghermit marked this conversation as resolved.
}
case *PluginSpecV1_Okta:
// Check settings.
if settings.Okta == nil {
Expand Down Expand Up @@ -266,6 +290,8 @@ func (p *PluginV1) GetType() PluginType {
return PluginTypeOpenAI
case *PluginSpecV1_Okta:
return PluginTypeOkta
case *PluginSpecV1_Jamf:
return PluginTypeJamf
default:
return PluginTypeUnknown
}
Expand Down
Loading