Skip to content

feat(cloud): add shared-instance flag in limit superflag in alpha #7770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 5, 2021
10 changes: 9 additions & 1 deletion dgraph/cmd/alpha/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ they form a Raft group and provide synchronous replication.
Flag("size",
"The audit log max size in MB after which it will be rolled over.").
String())

flag.String("cloud", worker.CloudDefaults, z.NewSuperFlagHelp(worker.CloudDefaults).
Head("Dgraph cloud options").
Flag("disable-non-galaxy",
"Disable ACL for non-galaxy users.").
String())
}

func setupCustomTokenizers() {
Expand Down Expand Up @@ -623,7 +629,8 @@ func run() {
pstoreBlockCacheSize, pstoreIndexCacheSize)
bopts := badger.DefaultOptions("").FromSuperFlag(worker.BadgerDefaults + cacheOpts).
FromSuperFlag(Alpha.Conf.GetString("badger"))

cloudMode := z.NewSuperFlag(Alpha.Conf.GetString("cloud")).
MergeAndCheckDefault(worker.CloudDefaults).GetBool("disable-non-galaxy")
security := z.NewSuperFlag(Alpha.Conf.GetString("security")).MergeAndCheckDefault(
worker.SecurityDefaults)
conf := audit.GetAuditConf(Alpha.Conf.GetString("audit"))
Expand All @@ -637,6 +644,7 @@ func run() {
AuthToken: security.GetString("token"),
Audit: conf,
ChangeDataConf: Alpha.Conf.GetString("cdc"),
CloudMode: cloudMode,
}

keys, err := ee.GetKeys(Alpha.Conf)
Expand Down
76 changes: 50 additions & 26 deletions edgraph/access_ee.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ type predsAndvars struct {
func (s *Server) Login(ctx context.Context,
request *api.LoginRequest) (*api.Response, error) {

if !shouldAllowAcls(request.GetNamespace()) {
return nil, errors.New("operation is not allowed in cloud mode")
}

if err := x.HealthCheck(); err != nil {
return nil, err
}
Expand Down Expand Up @@ -605,14 +609,11 @@ type authPredResult struct {
}

func authorizePreds(ctx context.Context, userData *userData, preds []string,
aclOp *acl.Operation) (*authPredResult, error) {
aclOp *acl.Operation) *authPredResult {

ns, err := x.ExtractNamespace(ctx)
if err != nil {
return nil, errors.Wrapf(err, "While authorizing preds")
}
userId := userData.userId
groupIds := userData.groupIds
ns := userData.namespace
blockedPreds := make(map[string]struct{})
for _, pred := range preds {
nsPred := x.NamespaceAttr(ns, pred)
Expand All @@ -638,7 +639,7 @@ func authorizePreds(ctx context.Context, userData *userData, preds []string,
}
}
aclCachePtr.RUnlock()
return &authPredResult{allowed: allowedPreds, blocked: blockedPreds}, nil
return &authPredResult{allowed: allowedPreds, blocked: blockedPreds}
}

// authorizeAlter parses the Schema in the operation and authorizes the operation
Expand Down Expand Up @@ -693,10 +694,7 @@ func authorizeAlter(ctx context.Context, op *api.Operation) error {
"only guardians are allowed to drop all data, but the current user is %s", userId)
}

result, err := authorizePreds(ctx, userData, preds, acl.Modify)
if err != nil {
return nil
}
result := authorizePreds(ctx, userData, preds, acl.Modify)
if len(result.blocked) > 0 {
var msg strings.Builder
for key := range result.blocked {
Expand Down Expand Up @@ -805,12 +803,17 @@ func authorizeMutation(ctx context.Context, gmu *gql.Mutation) error {
case isAclPredMutation(gmu.Del):
return errors.Errorf("ACL predicates can't be deleted")
}
if !shouldAllowAcls(userData.namespace) {
for _, pred := range preds {
if x.IsAclPredicate(pred) {
return status.Errorf(codes.PermissionDenied,
"unauthorized to mutate acl predicates: %s\n", pred)
}
}
}
return nil
}
result, err := authorizePreds(ctx, userData, preds, acl.Write)
if err != nil {
return err
}
result := authorizePreds(ctx, userData, preds, acl.Write)
if len(result.blocked) > 0 {
var msg strings.Builder
for key := range result.blocked {
Expand Down Expand Up @@ -918,7 +921,12 @@ func logAccess(log *accessEntry) {
}
}

//authorizeQuery authorizes the query using the aclCachePtr. It will silently drop all
// With cloud mode enabled, we don't allow ACL operations from any of the non-galaxy namespace.
func shouldAllowAcls(ns uint64) bool {
return !worker.Config.CloudMode || ns == x.GalaxyNamespace
}

// authorizeQuery authorizes the query using the aclCachePtr. It will silently drop all
// unauthorized predicates from query.
// At this stage, namespace is not attached in the predicates.
func authorizeQuery(ctx context.Context, parsedReq *gql.Result, graphql bool) error {
Expand All @@ -929,6 +937,7 @@ func authorizeQuery(ctx context.Context, parsedReq *gql.Result, graphql bool) er

var userId string
var groupIds []string
var namespace uint64
predsAndvars := parsePredsFromQuery(parsedReq.Query)
preds := predsAndvars.preds
varsToPredMap := predsAndvars.vars
Expand All @@ -948,14 +957,22 @@ func authorizeQuery(ctx context.Context, parsedReq *gql.Result, graphql bool) er

userId = userData.userId
groupIds = userData.groupIds
namespace = userData.namespace

if x.IsGuardian(groupIds) {
// Members of guardian groups are allowed to query anything.
return nil, nil, nil
if x.IsGuardian(groupIds) && shouldAllowAcls(namespace) {
if shouldAllowAcls(userData.namespace) {
// Members of guardian groups are allowed to query anything.
return nil, nil, nil
}
blocked := make(map[string]struct{})
for _, pred := range x.AllACLPredicates() {
blocked[pred] = struct{}{}
}
return blocked, nil, nil
}

result, err := authorizePreds(ctx, userData, preds, acl.Read)
return result.blocked, result.allowed, err
result := authorizePreds(ctx, userData, preds, acl.Read)
return result.blocked, result.allowed, nil
}

blockedPreds, allowedPreds, err := doAuthorizeQuery()
Expand All @@ -976,7 +993,7 @@ func authorizeQuery(ctx context.Context, parsedReq *gql.Result, graphql bool) er
if len(blockedPreds) != 0 {
// For GraphQL requests, we allow filtered access to the ACL predicates.
// Filter for user_id and group_id is applied for the currently logged in user.
if graphql {
if graphql && shouldAllowAcls(namespace) {
for _, gq := range parsedReq.Query {
addUserFilterToQuery(gq, userId, groupIds)
}
Expand Down Expand Up @@ -1036,12 +1053,19 @@ func authorizeSchemaQuery(ctx context.Context, er *query.ExecutionResult) error
}

groupIds := userData.groupIds
if x.IsGuardian(groupIds) {
// Members of guardian groups are allowed to query anything.
return nil, nil
if x.IsGuardian(groupIds) && shouldAllowAcls(userData.namespace) {
if shouldAllowAcls(userData.namespace) {
// Members of guardian groups are allowed to query anything.
return nil, nil
}
blocked := make(map[string]struct{})
for _, pred := range x.AllACLPredicates() {
blocked[pred] = struct{}{}
}
return blocked, nil
}
result, err := authorizePreds(ctx, userData, preds, acl.Read)
return result.blocked, err
result := authorizePreds(ctx, userData, preds, acl.Read)
return result.blocked, nil
}

// find the predicates which are blocked for the schema query
Expand Down
3 changes: 3 additions & 0 deletions worker/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ type Options struct {

// Define different ChangeDataCapture configurations
ChangeDataConf string

// Define different Cloud configurations.
CloudMode bool
}

// Config holds an instance of the server options..
Expand Down
15 changes: 8 additions & 7 deletions worker/server_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,19 @@ const (
// breaks.
AuditDefaults = `compress=false; days=10; size=100; dir=; output=; encrypt-file=;`
BadgerDefaults = `compression=snappy; numgoroutines=8;`
RaftDefaults = `learner=false; snapshot-after-entries=10000; ` +
`snapshot-after-duration=30m; pending-proposals=256; idx=; group=;`
SecurityDefaults = `token=; whitelist=;`
CDCDefaults = `file=; kafka=; sasl_user=; sasl_password=; ca_cert=; client_cert=; ` +
CacheDefaults = `size-mb=1024; percentage=0,65,35;`
CDCDefaults = `file=; kafka=; sasl_user=; sasl_password=; ca_cert=; client_cert=; ` +
`client_key=; sasl-mechanism=PLAIN;`
CloudDefaults = `disable-non-galaxy=false;`
GraphQLDefaults = `introspection=true; debug=false; extensions=true; poll-interval=1s; ` +
`lambda-url=;`
LimitDefaults = `mutations=allow; query-edge=1000000; normalize-node=10000; ` +
`mutations-nquad=1000000; disallow-drop=false; query-timeout=0ms; txn-abort-after=5m;` +
`max-pending-queries=10000; max-retries=-1;`
RaftDefaults = `learner=false; snapshot-after-entries=10000; ` +
`snapshot-after-duration=30m; pending-proposals=256; idx=; group=;`
SecurityDefaults = `token=; whitelist=;`
ZeroLimitsDefaults = `uid-lease=0; refill-interval=30s; disable-admin-http=false;`
GraphQLDefaults = `introspection=true; debug=false; extensions=true; poll-interval=1s; ` +
`lambda-url=;`
CacheDefaults = `size-mb=1024; percentage=0,65,35;`
)

// ServerState holds the state of the Dgraph server.
Expand Down