mirror of https://github.com/status-im/consul.git
Output user-friendly name for anonymous token (#15884)
This commit is contained in:
parent
644cd864a5
commit
a7b34d50fc
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:feature
|
||||||
|
acl: anonymous token is logged as 'anonymous token' instead of its accessor ID
|
||||||
|
```
|
16
acl/acl.go
16
acl/acl.go
|
@ -2,6 +2,12 @@ package acl
|
||||||
|
|
||||||
const (
|
const (
|
||||||
WildcardName = "*"
|
WildcardName = "*"
|
||||||
|
|
||||||
|
// AnonymousTokenID is the AccessorID of the anonymous token.
|
||||||
|
// When logging or displaying to users, use acl.AliasIfAnonymousToken
|
||||||
|
// to convert this to AnonymousTokenAlias.
|
||||||
|
AnonymousTokenID = "00000000-0000-0000-0000-000000000002"
|
||||||
|
AnonymousTokenAlias = "anonymous token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config encapsulates all of the generic configuration parameters used for
|
// Config encapsulates all of the generic configuration parameters used for
|
||||||
|
@ -43,3 +49,13 @@ func (c *Config) Close() {
|
||||||
c.EnterpriseConfig.Close()
|
c.EnterpriseConfig.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AliasIfAnonymousToken returns the string "anonymous token" if
|
||||||
|
// accessorID is acl.AnonymousTokenID. Used for better
|
||||||
|
// UX when logging the accessorID.
|
||||||
|
func AliasIfAnonymousToken(accessorID string) string {
|
||||||
|
if accessorID == AnonymousTokenID {
|
||||||
|
return AnonymousTokenAlias
|
||||||
|
}
|
||||||
|
return accessorID
|
||||||
|
}
|
||||||
|
|
|
@ -98,6 +98,8 @@ func (e PermissionDeniedError) Error() string {
|
||||||
|
|
||||||
if e.Accessor == "" {
|
if e.Accessor == "" {
|
||||||
message.WriteString(": provided token")
|
message.WriteString(": provided token")
|
||||||
|
} else if e.Accessor == AnonymousTokenID {
|
||||||
|
message.WriteString(": anonymous token")
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(&message, ": token with AccessorID '%s'", e.Accessor)
|
fmt.Fprintf(&message, ": token with AccessorID '%s'", e.Accessor)
|
||||||
}
|
}
|
||||||
|
@ -107,6 +109,10 @@ func (e PermissionDeniedError) Error() string {
|
||||||
if e.ResourceID.Name != "" {
|
if e.ResourceID.Name != "" {
|
||||||
fmt.Fprintf(&message, " on %s", e.ResourceID.ToString())
|
fmt.Fprintf(&message, " on %s", e.ResourceID.ToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if e.Accessor == AnonymousTokenID {
|
||||||
|
message.WriteString(". The anonymous token is used implicitly when a request does not specify a token.")
|
||||||
|
}
|
||||||
return message.String()
|
return message.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,10 @@ package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RequirePermissionDeniedError(t testing.TB, err error, authz Authorizer, _ *AuthorizerContext, resource Resource, accessLevel AccessLevel, resourceID string) {
|
func RequirePermissionDeniedError(t testing.TB, err error, authz Authorizer, _ *AuthorizerContext, resource Resource, accessLevel AccessLevel, resourceID string) {
|
||||||
|
|
|
@ -169,7 +169,7 @@ func (a *Agent) filterMembers(token string, members *[]serf.Member) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
accessorID := authz.AccessorID()
|
accessorID := authz.AccessorID()
|
||||||
a.logger.Debug("dropping node from result due to ACLs", "node", node, "accessorID", accessorID)
|
a.logger.Debug("dropping node from result due to ACLs", "node", node, "accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
m = append(m[:i], m[i+1:]...)
|
m = append(m[:i], m[i+1:]...)
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/proto/pboperator"
|
|
||||||
|
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
"github.com/armon/go-metrics/prometheus"
|
"github.com/armon/go-metrics/prometheus"
|
||||||
"github.com/hashicorp/go-connlimit"
|
"github.com/hashicorp/go-connlimit"
|
||||||
|
@ -66,6 +64,7 @@ import (
|
||||||
"github.com/hashicorp/consul/lib/mutex"
|
"github.com/hashicorp/consul/lib/mutex"
|
||||||
"github.com/hashicorp/consul/lib/routine"
|
"github.com/hashicorp/consul/lib/routine"
|
||||||
"github.com/hashicorp/consul/logging"
|
"github.com/hashicorp/consul/logging"
|
||||||
|
"github.com/hashicorp/consul/proto/pboperator"
|
||||||
"github.com/hashicorp/consul/proto/pbpeering"
|
"github.com/hashicorp/consul/proto/pbpeering"
|
||||||
"github.com/hashicorp/consul/tlsutil"
|
"github.com/hashicorp/consul/tlsutil"
|
||||||
"github.com/hashicorp/consul/types"
|
"github.com/hashicorp/consul/types"
|
||||||
|
@ -1956,12 +1955,10 @@ OUTER:
|
||||||
WriteRequest: structs.WriteRequest{Token: agentToken},
|
WriteRequest: structs.WriteRequest{Token: agentToken},
|
||||||
}
|
}
|
||||||
var reply struct{}
|
var reply struct{}
|
||||||
// todo(kit) port all of these logger calls to hclog w/ loglevel configuration
|
|
||||||
// todo(kit) handle acl.ErrNotFound cases here in the future
|
|
||||||
if err := a.RPC(context.Background(), "Coordinate.Update", &req, &reply); err != nil {
|
if err := a.RPC(context.Background(), "Coordinate.Update", &req, &reply); err != nil {
|
||||||
if acl.IsErrPermissionDenied(err) {
|
if acl.IsErrPermissionDenied(err) {
|
||||||
accessorID := a.aclAccessorID(agentToken)
|
accessorID := a.aclAccessorID(agentToken)
|
||||||
a.logger.Warn("Coordinate update blocked by ACLs", "accessorID", accessorID)
|
a.logger.Warn("Coordinate update blocked by ACLs", "accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
} else {
|
} else {
|
||||||
a.logger.Error("Coordinate update error", "error", err)
|
a.logger.Error("Coordinate update error", "error", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -718,7 +718,7 @@ func (r *ACLResolver) collectPoliciesForIdentity(identity structs.ACLIdentity, p
|
||||||
} else {
|
} else {
|
||||||
r.logger.Warn("policy not found for identity",
|
r.logger.Warn("policy not found for identity",
|
||||||
"policy", policyID,
|
"policy", policyID,
|
||||||
"accessorID", accessorID,
|
"accessorID", acl.AliasIfAnonymousToken(accessorID),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,7 +819,7 @@ func (r *ACLResolver) collectRolesForIdentity(identity structs.ACLIdentity, role
|
||||||
}
|
}
|
||||||
r.logger.Warn("role not found for identity",
|
r.logger.Warn("role not found for identity",
|
||||||
"role", roleID,
|
"role", roleID,
|
||||||
"accessorID", accessorID,
|
"accessorID", acl.AliasIfAnonymousToken(accessorID),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -574,7 +574,7 @@ func (a *ACL) TokenDelete(args *structs.ACLTokenDeleteRequest, reply *string) er
|
||||||
return fmt.Errorf("Accessor ID is missing or an invalid UUID")
|
return fmt.Errorf("Accessor ID is missing or an invalid UUID")
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.TokenID == structs.ACLTokenAnonymousID {
|
if args.TokenID == acl.AnonymousTokenID {
|
||||||
return fmt.Errorf("Delete operation not permitted on the anonymous token")
|
return fmt.Errorf("Delete operation not permitted on the anonymous token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
)
|
)
|
||||||
|
@ -56,7 +57,7 @@ func testACLTokenReap_Primary(t *testing.T, local, global bool) {
|
||||||
codec := rpcClient(t, s1)
|
codec := rpcClient(t, s1)
|
||||||
defer codec.Close()
|
defer codec.Close()
|
||||||
|
|
||||||
acl := ACL{srv: s1}
|
aclEp := ACL{srv: s1}
|
||||||
|
|
||||||
initialManagementTokenAccessorID, err := retrieveTestTokenAccessorForSecret(codec, "root", "dc1", "root")
|
initialManagementTokenAccessorID, err := retrieveTestTokenAccessorForSecret(codec, "root", "dc1", "root")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -68,7 +69,7 @@ func testACLTokenReap_Primary(t *testing.T, local, global bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var res structs.ACLTokenListResponse
|
var res structs.ACLTokenListResponse
|
||||||
err = acl.TokenList(&req, &res)
|
err = aclEp.TokenList(&req, &res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,7 @@ func testACLTokenReap_Primary(t *testing.T, local, global bool) {
|
||||||
// The initial management token and the anonymous token are always
|
// The initial management token and the anonymous token are always
|
||||||
// going to be present and global.
|
// going to be present and global.
|
||||||
expectGlobal = append(expectGlobal, initialManagementTokenAccessorID)
|
expectGlobal = append(expectGlobal, initialManagementTokenAccessorID)
|
||||||
expectGlobal = append(expectGlobal, structs.ACLTokenAnonymousID)
|
expectGlobal = append(expectGlobal, acl.AnonymousTokenID)
|
||||||
|
|
||||||
if local {
|
if local {
|
||||||
expectLocal = append(expectLocal, expect...)
|
expectLocal = append(expectLocal, expect...)
|
||||||
|
|
|
@ -176,11 +176,10 @@ func (s *Intention) computeApplyChangesLegacyCreate(
|
||||||
if !args.Intention.CanWrite(authz) {
|
if !args.Intention.CanWrite(authz) {
|
||||||
sn := args.Intention.SourceServiceName()
|
sn := args.Intention.SourceServiceName()
|
||||||
dn := args.Intention.DestinationServiceName()
|
dn := args.Intention.DestinationServiceName()
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
|
||||||
s.logger.Warn("Intention creation denied due to ACLs",
|
s.logger.Warn("Intention creation denied due to ACLs",
|
||||||
"source", sn.String(),
|
"source", sn.String(),
|
||||||
"destination", dn.String(),
|
"destination", dn.String(),
|
||||||
"accessorID", accessorID)
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +249,9 @@ func (s *Intention) computeApplyChangesLegacyUpdate(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ixn.CanWrite(authz) {
|
if !ixn.CanWrite(authz) {
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
s.logger.Warn("Update operation on intention denied due to ACLs",
|
||||||
s.logger.Warn("Update operation on intention denied due to ACLs", "intention", args.Intention.ID, "accessorID", accessorID)
|
"intention", args.Intention.ID,
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,11 +311,10 @@ func (s *Intention) computeApplyChangesUpsert(
|
||||||
if !args.Intention.CanWrite(authz) {
|
if !args.Intention.CanWrite(authz) {
|
||||||
sn := args.Intention.SourceServiceName()
|
sn := args.Intention.SourceServiceName()
|
||||||
dn := args.Intention.DestinationServiceName()
|
dn := args.Intention.DestinationServiceName()
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
|
||||||
s.logger.Warn("Intention upsert denied due to ACLs",
|
s.logger.Warn("Intention upsert denied due to ACLs",
|
||||||
"source", sn.String(),
|
"source", sn.String(),
|
||||||
"destination", dn.String(),
|
"destination", dn.String(),
|
||||||
"accessorID", accessorID)
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,8 +370,9 @@ func (s *Intention) computeApplyChangesLegacyDelete(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ixn.CanWrite(authz) {
|
if !ixn.CanWrite(authz) {
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
s.logger.Warn("Deletion operation on intention denied due to ACLs",
|
||||||
s.logger.Warn("Deletion operation on intention denied due to ACLs", "intention", args.Intention.ID, "accessorID", accessorID)
|
"intention", args.Intention.ID,
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,11 +392,10 @@ func (s *Intention) computeApplyChangesDelete(
|
||||||
if !args.Intention.CanWrite(authz) {
|
if !args.Intention.CanWrite(authz) {
|
||||||
sn := args.Intention.SourceServiceName()
|
sn := args.Intention.SourceServiceName()
|
||||||
dn := args.Intention.DestinationServiceName()
|
dn := args.Intention.DestinationServiceName()
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
|
||||||
s.logger.Warn("Intention delete denied due to ACLs",
|
s.logger.Warn("Intention delete denied due to ACLs",
|
||||||
"source", sn.String(),
|
"source", sn.String(),
|
||||||
"destination", dn.String(),
|
"destination", dn.String(),
|
||||||
"accessorID", accessorID)
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,8 +482,9 @@ func (s *Intention) Get(args *structs.IntentionQueryRequest, reply *structs.Inde
|
||||||
// If ACLs prevented any responses, error
|
// If ACLs prevented any responses, error
|
||||||
if len(reply.Intentions) == 0 {
|
if len(reply.Intentions) == 0 {
|
||||||
accessorID := authz.AccessorID()
|
accessorID := authz.AccessorID()
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
s.logger.Warn("Request to get intention denied due to ACLs",
|
||||||
s.logger.Warn("Request to get intention denied due to ACLs", "intention", args.IntentionID, "accessorID", accessorID)
|
"intention", args.IntentionID,
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,8 +617,9 @@ func (s *Intention) Match(args *structs.IntentionQueryRequest, reply *structs.In
|
||||||
if prefix := entry.Name; prefix != "" {
|
if prefix := entry.Name; prefix != "" {
|
||||||
if err := authz.ToAllowAuthorizer().IntentionReadAllowed(prefix, &authzContext); err != nil {
|
if err := authz.ToAllowAuthorizer().IntentionReadAllowed(prefix, &authzContext); err != nil {
|
||||||
accessorID := authz.AccessorID()
|
accessorID := authz.AccessorID()
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
s.logger.Warn("Operation on intention prefix denied due to ACLs",
|
||||||
s.logger.Warn("Operation on intention prefix denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
|
"prefix", prefix,
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -741,8 +742,9 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In
|
||||||
query.FillAuthzContext(&authzContext)
|
query.FillAuthzContext(&authzContext)
|
||||||
if err := authz.ToAllowAuthorizer().ServiceReadAllowed(prefix, &authzContext); err != nil {
|
if err := authz.ToAllowAuthorizer().ServiceReadAllowed(prefix, &authzContext); err != nil {
|
||||||
accessorID := authz.AccessorID()
|
accessorID := authz.AccessorID()
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
s.logger.Warn("test on intention denied due to ACLs",
|
||||||
s.logger.Warn("test on intention denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
|
"prefix", prefix,
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,7 +755,7 @@ func (m *Internal) EventFire(args *structs.EventFireRequest,
|
||||||
|
|
||||||
if err := authz.ToAllowAuthorizer().EventWriteAllowed(args.Name, nil); err != nil {
|
if err := authz.ToAllowAuthorizer().EventWriteAllowed(args.Name, nil); err != nil {
|
||||||
accessorID := authz.AccessorID()
|
accessorID := authz.AccessorID()
|
||||||
m.logger.Warn("user event blocked by ACLs", "event", args.Name, "accessorID", accessorID)
|
m.logger.Warn("user event blocked by ACLs", "event", args.Name, "accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -510,7 +510,7 @@ func (s *Server) initializeACLs(ctx context.Context) error {
|
||||||
// Ignoring expiration times to avoid an insertion collision.
|
// Ignoring expiration times to avoid an insertion collision.
|
||||||
if token == nil {
|
if token == nil {
|
||||||
token = &structs.ACLToken{
|
token = &structs.ACLToken{
|
||||||
AccessorID: structs.ACLTokenAnonymousID,
|
AccessorID: acl.AnonymousTokenID,
|
||||||
SecretID: anonymousToken,
|
SecretID: anonymousToken,
|
||||||
Description: "Anonymous Token",
|
Description: "Anonymous Token",
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
|
@ -595,7 +595,7 @@ func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error {
|
||||||
|
|
||||||
newToken := *token
|
newToken := *token
|
||||||
if token.SecretID == anonymousToken {
|
if token.SecretID == anonymousToken {
|
||||||
newToken.AccessorID = structs.ACLTokenAnonymousID
|
newToken.AccessorID = acl.AnonymousTokenID
|
||||||
} else {
|
} else {
|
||||||
accessor, err := lib.GenerateUUID(s.checkTokenUUID)
|
accessor, err := lib.GenerateUUID(s.checkTokenUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
tokenStore "github.com/hashicorp/consul/agent/token"
|
tokenStore "github.com/hashicorp/consul/agent/token"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
|
@ -2409,7 +2410,7 @@ func TestLeader_ACL_Initialization_AnonymousToken(t *testing.T) {
|
||||||
reqToken := structs.ACLTokenSetRequest{
|
reqToken := structs.ACLTokenSetRequest{
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
AccessorID: structs.ACLTokenAnonymousID,
|
AccessorID: acl.AnonymousTokenID,
|
||||||
SecretID: anonymousToken,
|
SecretID: anonymousToken,
|
||||||
Description: "Anonymous Token",
|
Description: "Anonymous Token",
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
|
|
|
@ -1047,7 +1047,7 @@ func TestRPC_LocalTokenStrippedOnForward(t *testing.T) {
|
||||||
tokenUpsertReq := structs.ACLTokenSetRequest{
|
tokenUpsertReq := structs.ACLTokenSetRequest{
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
AccessorID: structs.ACLTokenAnonymousID,
|
AccessorID: acl.AnonymousTokenID,
|
||||||
Policies: []structs.ACLTokenPolicyLink{
|
Policies: []structs.ACLTokenPolicyLink{
|
||||||
{
|
{
|
||||||
ID: kvPolicy.ID,
|
ID: kvPolicy.ID,
|
||||||
|
@ -1225,7 +1225,7 @@ func TestRPC_LocalTokenStrippedOnForward_GRPC(t *testing.T) {
|
||||||
tokenUpsertReq := structs.ACLTokenSetRequest{
|
tokenUpsertReq := structs.ACLTokenSetRequest{
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
ACLToken: structs.ACLToken{
|
ACLToken: structs.ACLToken{
|
||||||
AccessorID: structs.ACLTokenAnonymousID,
|
AccessorID: acl.AnonymousTokenID,
|
||||||
Policies: []structs.ACLTokenPolicyLink{
|
Policies: []structs.ACLTokenPolicyLink{
|
||||||
{ID: policy.ID},
|
{ID: policy.ID},
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
memdb "github.com/hashicorp/go-memdb"
|
"github.com/hashicorp/go-memdb"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
pbacl "github.com/hashicorp/consul/proto/pbacl"
|
"github.com/hashicorp/consul/proto/pbacl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ACLTokens is used when saving a snapshot
|
// ACLTokens is used when saving a snapshot
|
||||||
|
@ -839,7 +839,7 @@ func aclTokenDeleteTxn(tx WriteTxn, idx uint64, value, index string, entMeta *ac
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if token.(*structs.ACLToken).AccessorID == structs.ACLTokenAnonymousID {
|
if token.(*structs.ACLToken).AccessorID == acl.AnonymousTokenID {
|
||||||
return fmt.Errorf("Deletion of the builtin anonymous token is not permitted")
|
return fmt.Errorf("Deletion of the builtin anonymous token is not permitted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ func setupGlobalManagement(t *testing.T, s *Store) {
|
||||||
|
|
||||||
func setupAnonymous(t *testing.T, s *Store) {
|
func setupAnonymous(t *testing.T, s *Store) {
|
||||||
token := structs.ACLToken{
|
token := structs.ACLToken{
|
||||||
AccessorID: structs.ACLTokenAnonymousID,
|
AccessorID: acl.AnonymousTokenID,
|
||||||
SecretID: "anonymous",
|
SecretID: "anonymous",
|
||||||
Description: "Anonymous Token",
|
Description: "Anonymous Token",
|
||||||
}
|
}
|
||||||
|
@ -979,7 +979,7 @@ func TestStateStore_ACLToken_List(t *testing.T) {
|
||||||
role: "",
|
role: "",
|
||||||
methodName: "",
|
methodName: "",
|
||||||
accessors: []string{
|
accessors: []string{
|
||||||
structs.ACLTokenAnonymousID,
|
acl.AnonymousTokenID,
|
||||||
"47eea4da-bda1-48a6-901c-3e36d2d9262f", // policy + global
|
"47eea4da-bda1-48a6-901c-3e36d2d9262f", // policy + global
|
||||||
"54866514-3cf2-4fec-8a8a-710583831834", // mgmt + global
|
"54866514-3cf2-4fec-8a8a-710583831834", // mgmt + global
|
||||||
"74277ae1-6a9b-4035-b444-2370fe6a2cb5", // authMethod + global
|
"74277ae1-6a9b-4035-b444-2370fe6a2cb5", // authMethod + global
|
||||||
|
@ -1098,7 +1098,7 @@ func TestStateStore_ACLToken_List(t *testing.T) {
|
||||||
role: "",
|
role: "",
|
||||||
methodName: "",
|
methodName: "",
|
||||||
accessors: []string{
|
accessors: []string{
|
||||||
structs.ACLTokenAnonymousID,
|
acl.AnonymousTokenID,
|
||||||
"211f0360-ef53-41d3-9d4d-db84396eb6c0", // authMethod + local
|
"211f0360-ef53-41d3-9d4d-db84396eb6c0", // authMethod + local
|
||||||
"47eea4da-bda1-48a6-901c-3e36d2d9262f", // policy + global
|
"47eea4da-bda1-48a6-901c-3e36d2d9262f", // policy + global
|
||||||
"4915fc9d-3726-4171-b588-6c271f45eecd", // policy + local
|
"4915fc9d-3726-4171-b588-6c271f45eecd", // policy + local
|
||||||
|
@ -1476,7 +1476,7 @@ func TestStateStore_ACLToken_Delete(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
s := testACLTokensStateStore(t)
|
s := testACLTokensStateStore(t)
|
||||||
|
|
||||||
require.Error(t, s.ACLTokenDeleteByAccessor(3, structs.ACLTokenAnonymousID, nil))
|
require.Error(t, s.ACLTokenDeleteByAccessor(3, acl.AnonymousTokenID, nil))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Not Found", func(t *testing.T) {
|
t.Run("Not Found", func(t *testing.T) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ func ACLAnonymous(t *testing.T) resolver.Result {
|
||||||
return resolver.Result{
|
return resolver.Result{
|
||||||
Authorizer: acl.DenyAll(),
|
Authorizer: acl.DenyAll(),
|
||||||
ACLIdentity: &structs.ACLToken{
|
ACLIdentity: &structs.ACLToken{
|
||||||
AccessorID: structs.ACLTokenAnonymousID,
|
AccessorID: acl.AnonymousTokenID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/acl/resolver"
|
"github.com/hashicorp/consul/acl/resolver"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// We tag logs with a unique identifier to ease debugging. In the future this
|
// We tag logs with a unique identifier to ease debugging. In the future this
|
||||||
|
@ -36,7 +35,7 @@ func RequireAnyValidACLToken(resolver ACLResolver, token string) error {
|
||||||
return status.Error(codes.Unauthenticated, err.Error())
|
return status.Error(codes.Unauthenticated, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if id := authz.ACLIdentity; id != nil && id.ID() == structs.ACLTokenAnonymousID {
|
if id := authz.ACLIdentity; id != nil && id.ID() == acl.AnonymousTokenID {
|
||||||
return status.Error(codes.Unauthenticated, "An ACL token must be provided (via the `x-consul-token` metadata field) to call this endpoint")
|
return status.Error(codes.Unauthenticated, "An ACL token must be provided (via the `x-consul-token` metadata field) to call this endpoint")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1301,7 +1301,9 @@ func (l *State) deleteService(key structs.ServiceID) error {
|
||||||
// todo(fs): some backoff strategy might be a better solution
|
// todo(fs): some backoff strategy might be a better solution
|
||||||
l.services[key].InSync = true
|
l.services[key].InSync = true
|
||||||
accessorID := l.aclAccessorID(st)
|
accessorID := l.aclAccessorID(st)
|
||||||
l.logger.Warn("Service deregistration blocked by ACLs", "service", key.String(), "accessorID", accessorID)
|
l.logger.Warn("Service deregistration blocked by ACLs",
|
||||||
|
"service", key.String(),
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
metrics.IncrCounter([]string{"acl", "blocked", "service", "deregistration"}, 1)
|
metrics.IncrCounter([]string{"acl", "blocked", "service", "deregistration"}, 1)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
@ -1341,7 +1343,9 @@ func (l *State) deleteCheck(key structs.CheckID) error {
|
||||||
// todo(fs): some backoff strategy might be a better solution
|
// todo(fs): some backoff strategy might be a better solution
|
||||||
l.checks[key].InSync = true
|
l.checks[key].InSync = true
|
||||||
accessorID := l.aclAccessorID(ct)
|
accessorID := l.aclAccessorID(ct)
|
||||||
l.logger.Warn("Check deregistration blocked by ACLs", "check", key.String(), "accessorID", accessorID)
|
l.logger.Warn("Check deregistration blocked by ACLs",
|
||||||
|
"check", key.String(),
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
metrics.IncrCounter([]string{"acl", "blocked", "check", "deregistration"}, 1)
|
metrics.IncrCounter([]string{"acl", "blocked", "check", "deregistration"}, 1)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
@ -1430,7 +1434,9 @@ func (l *State) syncService(key structs.ServiceID) error {
|
||||||
l.checks[checkKey].InSync = true
|
l.checks[checkKey].InSync = true
|
||||||
}
|
}
|
||||||
accessorID := l.aclAccessorID(st)
|
accessorID := l.aclAccessorID(st)
|
||||||
l.logger.Warn("Service registration blocked by ACLs", "service", key.String(), "accessorID", accessorID)
|
l.logger.Warn("Service registration blocked by ACLs",
|
||||||
|
"service", key.String(),
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
metrics.IncrCounter([]string{"acl", "blocked", "service", "registration"}, 1)
|
metrics.IncrCounter([]string{"acl", "blocked", "service", "registration"}, 1)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
@ -1484,7 +1490,9 @@ func (l *State) syncCheck(key structs.CheckID) error {
|
||||||
// todo(fs): some backoff strategy might be a better solution
|
// todo(fs): some backoff strategy might be a better solution
|
||||||
l.checks[key].InSync = true
|
l.checks[key].InSync = true
|
||||||
accessorID := l.aclAccessorID(ct)
|
accessorID := l.aclAccessorID(ct)
|
||||||
l.logger.Warn("Check registration blocked by ACLs", "check", key.String(), "accessorID", accessorID)
|
l.logger.Warn("Check registration blocked by ACLs",
|
||||||
|
"check", key.String(),
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
metrics.IncrCounter([]string{"acl", "blocked", "check", "registration"}, 1)
|
metrics.IncrCounter([]string{"acl", "blocked", "check", "registration"}, 1)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
@ -1522,7 +1530,9 @@ func (l *State) syncNodeInfo() error {
|
||||||
// todo(fs): some backoff strategy might be a better solution
|
// todo(fs): some backoff strategy might be a better solution
|
||||||
l.nodeInfoInSync = true
|
l.nodeInfoInSync = true
|
||||||
accessorID := l.aclAccessorID(at)
|
accessorID := l.aclAccessorID(at)
|
||||||
l.logger.Warn("Node info update blocked by ACLs", "node", l.config.NodeID, "accessorID", accessorID)
|
l.logger.Warn("Node info update blocked by ACLs",
|
||||||
|
"node", l.config.NodeID,
|
||||||
|
"accessorID", acl.AliasIfAnonymousToken(accessorID))
|
||||||
metrics.IncrCounter([]string{"acl", "blocked", "node", "registration"}, 1)
|
metrics.IncrCounter([]string{"acl", "blocked", "node", "registration"}, 1)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,6 @@ session_prefix "" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}` + EnterpriseACLPolicyGlobalManagement
|
}` + EnterpriseACLPolicyGlobalManagement
|
||||||
|
|
||||||
// This is the policy ID for anonymous access. This is configurable by the
|
|
||||||
// user.
|
|
||||||
ACLTokenAnonymousID = "00000000-0000-0000-0000-000000000002"
|
|
||||||
|
|
||||||
ACLReservedPrefix = "00000000-0000-0000-0000-0000000000"
|
ACLReservedPrefix = "00000000-0000-0000-0000-0000000000"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetTokenIDFromPartial(client *api.Client, partialID string) (string, error) {
|
func GetTokenIDFromPartial(client *api.Client, partialID string) (string, error) {
|
||||||
if partialID == "anonymous" {
|
if partialID == "anonymous" {
|
||||||
return structs.ACLTokenAnonymousID, nil
|
return acl.AnonymousTokenID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// the full UUID string was given
|
// the full UUID string was given
|
||||||
|
|
Loading…
Reference in New Issue