-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
authz: add audit logging APIs (#6158)
- Loading branch information
Showing
1 changed file
with
126 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* | ||
* Copyright 2023 gRPC authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*/ | ||
|
||
package authz | ||
|
||
import ( | ||
"encoding/json" | ||
"sync" | ||
) | ||
|
||
// loggerBuilderRegistry holds a map of audit logger builders and a mutex | ||
// to facilitate thread-safe reading/writing operations. | ||
type loggerBuilderRegistry struct { | ||
mu sync.Mutex | ||
builders map[string]AuditLoggerBuilder | ||
} | ||
|
||
var ( | ||
registry = loggerBuilderRegistry{ | ||
builders: make(map[string]AuditLoggerBuilder), | ||
} | ||
) | ||
|
||
// RegisterAuditLoggerBuilder registers the builder in a global map | ||
// using b.Name() as the key. | ||
// | ||
// This should only be called during initialization time (i.e. in an init() | ||
// function). If multiple builders are registered with the same name, | ||
// the one registered last will take effect. | ||
func RegisterAuditLoggerBuilder(b AuditLoggerBuilder) { | ||
registry.mu.Lock() | ||
defer registry.mu.Unlock() | ||
registry.builders[b.Name()] = b | ||
} | ||
|
||
// GetAuditLoggerBuilder returns a builder with the given name. | ||
// It returns nil if the builder is not found in the registry. | ||
func GetAuditLoggerBuilder(name string) AuditLoggerBuilder { | ||
registry.mu.Lock() | ||
defer registry.mu.Unlock() | ||
return registry.builders[name] | ||
} | ||
|
||
// AuditEvent contains information passed to the audit logger as part of an | ||
// audit logging event. | ||
type AuditEvent struct { | ||
// FullMethodName is the full method name of the audited RPC, in the format | ||
// of "/pkg.Service/Method". For example, "/helloworld.Greeter/SayHello". | ||
FullMethodName string | ||
// Principal is the identity of the caller. Currently it will only be | ||
// available in certificate-based TLS authentication. | ||
Principal string | ||
// PolicyName is the authorization policy name or the xDS RBAC filter name. | ||
PolicyName string | ||
// MatchedRule is the matched rule or policy name in the xDS RBAC filter. | ||
// It will be empty if there is no match. | ||
MatchedRule string | ||
// Authorized indicates whether the audited RPC is authorized or not. | ||
Authorized bool | ||
} | ||
|
||
// AuditLoggerConfig represents an opaque data structure holding an audit | ||
// logger configuration. Concrete types representing configuration of specific | ||
// audit loggers must embed this interface to implement it. | ||
type AuditLoggerConfig interface { | ||
auditLoggerConfig() | ||
} | ||
|
||
// AuditLogger is the interface to be implemented by audit loggers. | ||
// | ||
// An audit logger is a logger instance that can be configured via the | ||
// authorization policy API or xDS HTTP RBAC filters. When the authorization | ||
// decision meets the condition for audit, all the configured audit loggers' | ||
// Log() method will be invoked to log that event. | ||
// | ||
// TODO(lwge): Change the link to the merged gRFC once it's ready. | ||
// Please refer to https://github.com/grpc/proposal/pull/346 for more details | ||
// about audit logging. | ||
type AuditLogger interface { | ||
// Log performs audit logging for the provided audit event. | ||
// | ||
// This method is invoked in the RPC path and therefore implementations | ||
// must not block. | ||
Log(*AuditEvent) | ||
} | ||
|
||
// AuditLoggerBuilder is the interface to be implemented by audit logger | ||
// builders that are used at runtime to configure and instantiate audit loggers. | ||
// | ||
// Users who want to implement their own audit logging logic should | ||
// implement this interface, along with the AuditLogger interface, and register | ||
// it by calling RegisterAuditLoggerBuilder() at init time. | ||
// | ||
// TODO(lwge): Change the link to the merged gRFC once it's ready. | ||
// Please refer to https://github.com/grpc/proposal/pull/346 for more details | ||
// about audit logging. | ||
type AuditLoggerBuilder interface { | ||
// ParseAuditLoggerConfig parses the given JSON bytes into a structured | ||
// logger config this builder can use to build an audit logger. | ||
ParseAuditLoggerConfig(config json.RawMessage) (AuditLoggerConfig, error) | ||
// Build builds an audit logger with the given logger config. | ||
// This will only be called with valid configs returned from | ||
// ParseAuditLoggerConfig() and any runtime issues such as failing to | ||
// create a file should be handled by the logger implementation instead of | ||
// failing the logger instantiation. So implementers need to make sure it | ||
// can return a logger without error at this stage. | ||
Build(AuditLoggerConfig) AuditLogger | ||
// Name returns the name of logger built by this builder. | ||
// This is used to register and pick the builder. | ||
Name() string | ||
} |