Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions proto/redpanda/core/admin/v2/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ proto_library(
"//proto/redpanda/core/pbgen:rpc_proto",
"@googleapis//google/api:field_behavior_proto",
"@googleapis//google/api:resource_proto",
"@protobuf//:field_mask_proto",
"@protobuf//:timestamp_proto",
],
)
Expand All @@ -117,6 +118,7 @@ redpanda_proto_library(
],
visibility = ["//visibility:public"],
deps = [
"//src/v/serde/protobuf:field_mask",
"@abseil-cpp//absl/time:time",
],
)
156 changes: 156 additions & 0 deletions proto/redpanda/core/admin/v2/security.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,62 @@ import "proto/redpanda/core/pbgen/rpc.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";

option (pbgen.cpp_namespace) = "proto::admin";

// The SecurityService provides security-related operations.
service SecurityService {
// CreateScramCredential
//
// Create a SCRAM credential.
rpc CreateScramCredential(CreateScramCredentialRequest)
returns (CreateScramCredentialResponse) {
option (pbgen.rpc) = {
authz: SUPERUSER
};
}

// GetScramCredential
//
// Retrieve a SCRAM credential.
rpc GetScramCredential(GetScramCredentialRequest)
returns (GetScramCredentialResponse) {
option (pbgen.rpc) = {
authz: SUPERUSER
};
}

// ListScramCredentials
//
// List all SCRAM credentials.
rpc ListScramCredentials(ListScramCredentialsRequest)
returns (ListScramCredentialsResponse) {
option (pbgen.rpc) = {
authz: SUPERUSER
};
}

// UpdateScramCredential
//
// Update a SCRAM credential.
rpc UpdateScramCredential(UpdateScramCredentialRequest)
returns (UpdateScramCredentialResponse) {
option (pbgen.rpc) = {
authz: SUPERUSER
};
}

// DeleteScramCredential
//
// Delete a SCRAM credential.
rpc DeleteScramCredential(DeleteScramCredentialRequest)
returns (DeleteScramCredentialResponse) {
option (pbgen.rpc) = {
authz: SUPERUSER
};
}

// CreateRole
//
// Create a new Role resource.
Expand Down Expand Up @@ -134,6 +185,34 @@ service SecurityService {
/* Resources */
// =============================================

// The ScramCredential resource used for SCRAM authentication.
message ScramCredential {
option (google.api.resource) = {
type: "redpanda.core.admin.SecurityService/ScramCredential"
pattern: "scram_credentials/{scram_credential}"
};

// The name of the SCRAM credential.
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.field_behavior) = IMMUTABLE
];

// The SCRAM mechanism.
enum ScramMechanism {
SCRAM_MECHANISM_UNSPECIFIED = 0;
SCRAM_MECHANISM_SCRAM_SHA_256 = 1;
SCRAM_MECHANISM_SCRAM_SHA_512 = 2;
}
Comment on lines +201 to +206
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if it would be useful to extract this to a common area of security. Maybe a security_types.proto


// The SCRAM mechanism used for this credential.
ScramMechanism mechanism = 2;

// The password for the SCRAM credential.
string password = 3
[debug_redact = true, (google.api.field_behavior) = INPUT_ONLY];
Comment on lines +211 to +213
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should also add a password_set_at field (a, la

// Timestamp of when the password was last set - only valid if password_set
// is true
google.protobuf.Timestamp password_set_at = 4
[(google.api.field_behavior) = OUTPUT_ONLY];
). This is so processes that are attempting to reconcile can have a signal as to when was the last time the password was changed.

I do think this may result in having to make controller updates to store the timestamp.

}

// The Role resource represents a security role with associated members.
message Role {
option (google.api.resource) = {
Expand All @@ -155,6 +234,83 @@ message Role {
/* RPC Requests and Responses */
// =============================================

// CreateScramCredentialRequest is the request for the CreateScramCredential
// RPC.
message CreateScramCredentialRequest {
// The SCRAM credential to create.
ScramCredential scram_credential = 1
[(google.api.field_behavior) = REQUIRED];
}

// CreateScramCredentialResponse is the response from the CreateScramCredential
// RPC.
message CreateScramCredentialResponse {
// The created SCRAM credential.
ScramCredential scram_credential = 1;
}

// GetScramCredentialRequest is the request for the GetScramCredential RPC.
message GetScramCredentialRequest {
// The name of the SCRAM credential to retrieve.
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "redpanda.core.admin.SecurityService/ScramCredential"
}
];
}

// GetScramCredentialResponse is the response from the GetScramCredential RPC.
message GetScramCredentialResponse {
// The requested SCRAM credential.
ScramCredential scram_credential = 1;
}

// ListScramCredentialsRequest is the request for the ListScramCredentials RPC.
message ListScramCredentialsRequest {}

// ListScramCredentialsResponse is the response from the ListScramCredentials
// RPC.
message ListScramCredentialsResponse {
// The list of SCRAM credentials.
repeated ScramCredential scram_credentials = 1;
}

// UpdateScramCredentialRequest is the request for the UpdateScramCredential
// RPC.
message UpdateScramCredentialRequest {
// The SCRAM credential to update.
ScramCredential scram_credential = 1
[(google.api.field_behavior) = REQUIRED];

// The list of fields to update
// See [AIP-134](https://google.aip.dev/134) for how to use `field_mask`
google.protobuf.FieldMask update_mask = 2;
}

// UpdateScramCredentialResponse is the response from the UpdateScramCredential
// RPC.
message UpdateScramCredentialResponse {
// The updated SCRAM credential.
ScramCredential scram_credential = 1;
}

// DeleteScramCredentialRequest is the request for the DeleteScramCredential
// RPC.
message DeleteScramCredentialRequest {
// The name of the SCRAM credential to delete.
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "redpanda.core.admin.SecurityService/ScramCredential"
}
];
}

// DeleteScramCredentialResponse is the response from the DeleteScramCredential
// RPC.
message DeleteScramCredentialResponse {}

// CreateRoleRequest is the request for the CreateRole RPC.
message CreateRoleRequest {
// The Role to create.
Expand Down
31 changes: 31 additions & 0 deletions src/v/redpanda/admin/services/security.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "security/role.h"
#include "security/role_store.h"
#include "security/scram_algorithm.h"
#include "serde/protobuf/rpc.h"

namespace admin {

Expand Down Expand Up @@ -151,6 +152,36 @@ security_service_impl::security_service_impl(
, _kafka_server(kafka_server)
, _md_cache(md_cache) {}

seastar::future<proto::admin::create_scram_credential_response>
security_service_impl::create_scram_credential(
serde::pb::rpc::context, proto::admin::create_scram_credential_request) {
throw serde::pb::rpc::unimplemented_exception("Not implemented");
}

seastar::future<proto::admin::get_scram_credential_response>
security_service_impl::get_scram_credential(
serde::pb::rpc::context, proto::admin::get_scram_credential_request) {
throw serde::pb::rpc::unimplemented_exception("Not implemented");
}

seastar::future<proto::admin::list_scram_credentials_response>
security_service_impl::list_scram_credentials(
serde::pb::rpc::context, proto::admin::list_scram_credentials_request) {
throw serde::pb::rpc::unimplemented_exception("Not implemented");
}

seastar::future<proto::admin::update_scram_credential_response>
security_service_impl::update_scram_credential(
serde::pb::rpc::context, proto::admin::update_scram_credential_request) {
throw serde::pb::rpc::unimplemented_exception("Not implemented");
}

seastar::future<proto::admin::delete_scram_credential_response>
security_service_impl::delete_scram_credential(
serde::pb::rpc::context, proto::admin::delete_scram_credential_request) {
throw serde::pb::rpc::unimplemented_exception("Not implemented");
}

seastar::future<proto::admin::create_role_response>
security_service_impl::create_role(
serde::pb::rpc::context ctx, proto::admin::create_role_request req) {
Expand Down
25 changes: 25 additions & 0 deletions src/v/redpanda/admin/services/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,31 @@ class security_service_impl : public proto::admin::security_service {
ss::sharded<kafka::server>& kafka_server,
ss::sharded<cluster::metadata_cache>& md_cache);

seastar::future<proto::admin::create_scram_credential_response>
create_scram_credential(
serde::pb::rpc::context,
proto::admin::create_scram_credential_request) override;

seastar::future<proto::admin::get_scram_credential_response>
get_scram_credential(
serde::pb::rpc::context,
proto::admin::get_scram_credential_request) override;

seastar::future<proto::admin::list_scram_credentials_response>
list_scram_credentials(
serde::pb::rpc::context,
proto::admin::list_scram_credentials_request) override;

seastar::future<proto::admin::update_scram_credential_response>
update_scram_credential(
serde::pb::rpc::context,
proto::admin::update_scram_credential_request) override;

seastar::future<proto::admin::delete_scram_credential_response>
delete_scram_credential(
serde::pb::rpc::context,
proto::admin::delete_scram_credential_request) override;

seastar::future<proto::admin::create_role_response> create_role(
serde::pb::rpc::context, proto::admin::create_role_request) override;

Expand Down