audit_logger.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. *
  3. * Copyright 2023 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package audit contains interfaces for audit logging during authorization.
  19. package audit
  20. import (
  21. "encoding/json"
  22. "sync"
  23. )
  24. // loggerBuilderRegistry holds a map of audit logger builders and a mutex
  25. // to facilitate thread-safe reading/writing operations.
  26. type loggerBuilderRegistry struct {
  27. mu sync.Mutex
  28. builders map[string]LoggerBuilder
  29. }
  30. var (
  31. registry = loggerBuilderRegistry{
  32. builders: make(map[string]LoggerBuilder),
  33. }
  34. )
  35. // RegisterLoggerBuilder registers the builder in a global map
  36. // using b.Name() as the key.
  37. //
  38. // This should only be called during initialization time (i.e. in an init()
  39. // function). If multiple builders are registered with the same name,
  40. // the one registered last will take effect.
  41. func RegisterLoggerBuilder(b LoggerBuilder) {
  42. registry.mu.Lock()
  43. defer registry.mu.Unlock()
  44. registry.builders[b.Name()] = b
  45. }
  46. // GetLoggerBuilder returns a builder with the given name.
  47. // It returns nil if the builder is not found in the registry.
  48. func GetLoggerBuilder(name string) LoggerBuilder {
  49. registry.mu.Lock()
  50. defer registry.mu.Unlock()
  51. return registry.builders[name]
  52. }
  53. // Event contains information passed to the audit logger as part of an
  54. // audit logging event.
  55. type Event struct {
  56. // FullMethodName is the full method name of the audited RPC, in the format
  57. // of "/pkg.Service/Method". For example, "/helloworld.Greeter/SayHello".
  58. FullMethodName string
  59. // Principal is the identity of the caller. Currently it will only be
  60. // available in certificate-based TLS authentication.
  61. Principal string
  62. // PolicyName is the authorization policy name or the xDS RBAC filter name.
  63. PolicyName string
  64. // MatchedRule is the matched rule or policy name in the xDS RBAC filter.
  65. // It will be empty if there is no match.
  66. MatchedRule string
  67. // Authorized indicates whether the audited RPC is authorized or not.
  68. Authorized bool
  69. }
  70. // LoggerConfig represents an opaque data structure holding an audit
  71. // logger configuration. Concrete types representing configuration of specific
  72. // audit loggers must embed this interface to implement it.
  73. type LoggerConfig interface {
  74. loggerConfig()
  75. }
  76. // Logger is the interface to be implemented by audit loggers.
  77. //
  78. // An audit logger is a logger instance that can be configured via the
  79. // authorization policy API or xDS HTTP RBAC filters. When the authorization
  80. // decision meets the condition for audit, all the configured audit loggers'
  81. // Log() method will be invoked to log that event.
  82. //
  83. // TODO(lwge): Change the link to the merged gRFC once it's ready.
  84. // Please refer to https://github.com/grpc/proposal/pull/346 for more details
  85. // about audit logging.
  86. type Logger interface {
  87. // Log performs audit logging for the provided audit event.
  88. //
  89. // This method is invoked in the RPC path and therefore implementations
  90. // must not block.
  91. Log(*Event)
  92. }
  93. // LoggerBuilder is the interface to be implemented by audit logger
  94. // builders that are used at runtime to configure and instantiate audit loggers.
  95. //
  96. // Users who want to implement their own audit logging logic should
  97. // implement this interface, along with the Logger interface, and register
  98. // it by calling RegisterLoggerBuilder() at init time.
  99. //
  100. // TODO(lwge): Change the link to the merged gRFC once it's ready.
  101. // Please refer to https://github.com/grpc/proposal/pull/346 for more details
  102. // about audit logging.
  103. type LoggerBuilder interface {
  104. // ParseLoggerConfig parses the given JSON bytes into a structured
  105. // logger config this builder can use to build an audit logger.
  106. ParseLoggerConfig(config json.RawMessage) (LoggerConfig, error)
  107. // Build builds an audit logger with the given logger config.
  108. // This will only be called with valid configs returned from
  109. // ParseLoggerConfig() and any runtime issues such as failing to
  110. // create a file should be handled by the logger implementation instead of
  111. // failing the logger instantiation. So implementers need to make sure it
  112. // can return a logger without error at this stage.
  113. Build(LoggerConfig) Logger
  114. // Name returns the name of logger built by this builder.
  115. // This is used to register and pick the builder.
  116. Name() string
  117. }