-
Notifications
You must be signed in to change notification settings - Fork 50
Session token V2 #3671
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
base: master
Are you sure you want to change the base?
Session token V2 #3671
Conversation
5bba446 to
f730e2f
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #3671 +/- ##
==========================================
- Coverage 25.60% 25.55% -0.06%
==========================================
Files 657 658 +1
Lines 42097 42468 +371
==========================================
+ Hits 10780 10852 +72
- Misses 30338 30613 +275
- Partials 979 1003 +24 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
41ab8d0 to
e66bf4b
Compare
eed01c8 to
f9d051d
Compare
5b82365 to
cea1b4d
Compare
cea1b4d to
2122d4d
Compare
eb453b4 to
1a9aab2
Compare
| type nnsResolver struct { | ||
| fsChain FSChain | ||
|
|
||
| nnsCache *lru.Cache[string, bool] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nns checks never expire (if size is big enough)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reset cache with the (s *Server) ResetSessionTokenCheckCache().
1a9aab2 to
b39cd77
Compare
cmd/neofs-cli/modules/object/util.go
Outdated
| verb = sessionv2.VerbObjectDelete | ||
| // For DELETE, create context with two verbs: | ||
| // 1. DELETE for the deleted object | ||
| // 2. PUT for the tombstone |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be required, tombstone PUT is DELETE ACL-wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, using Put without objects is more logical for verification than Delete with an object tombstone whose ID we don't know yet.
neofs-node/pkg/services/object/acl/v2/service.go
Lines 638 to 646 in 3f6a367
| op, verb, verbv2 := acl.OpObjectPut, sessionSDK.VerbObjectPut, sessionSDKv2.VerbObjectPut | |
| tombstone := header.GetObjectType() == protoobject.ObjectType_TOMBSTONE | |
| if tombstone { | |
| // such objects are specific - saving them is essentially the removal of other | |
| // objects | |
| op, verb = acl.OpObjectDelete, sessionSDK.VerbObjectDelete | |
| } | |
| reqInfo, err := b.findRequestInfo(request, cnr, op, verb, verbv2, obj) |
If I check Delete without objects here, it will be a bad check for the initial request with the object that needs to be deleted. There is no need to check Put with an object, because the ID is usually generated after the token is signed.
neofs-node/pkg/services/object/acl/v2/service.go
Lines 375 to 382 in 3f6a367
| // When we PUT a tombstone, the requested object is not zero, | |
| // but the session is not bound to it because the user cannot predict its ID. | |
| if !reqObj.IsZero() && reqVerb != sessionSDKv2.VerbObjectPut { | |
| if !token.AssertObject(reqVerb, reqCnr, reqObj) { | |
| return errors.New("v2 session token does not authorize access to the object") | |
| } | |
| } else { | |
| if !token.AssertVerb(reqVerb, reqCnr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meaning of OID for DELETE is to represent deleted OID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems strange and incorrect to me when the request changes from PUT for the tombstone to DELETE with the OID of the tombstone itself. In that case, I suggest specifying zero OID for Put with a tombstone here:
neofs-node/pkg/services/object/acl/v2/service.go
Lines 638 to 646 in 3f6a367
| op, verb, verbv2 := acl.OpObjectPut, sessionSDK.VerbObjectPut, sessionSDKv2.VerbObjectPut | |
| tombstone := header.GetObjectType() == protoobject.ObjectType_TOMBSTONE | |
| if tombstone { | |
| // such objects are specific - saving them is essentially the removal of other | |
| // objects | |
| op, verb = acl.OpObjectDelete, sessionSDK.VerbObjectDelete | |
| } | |
| reqInfo, err := b.findRequestInfo(request, cnr, op, verb, verbv2, obj) |
And replace
PUT with DELETE, as for token v1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why zero? Rather it can be an associated ID, we know it from the header.
pkg/services/container/server.go
Outdated
| } | ||
|
|
||
| func (r nnsResolver) HasUser(name string, userID user.ID) (bool, error) { | ||
| cacheKey := fmt.Sprintf("%s|%s", name, userID.String()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not very efficient.
ee17ebb to
3f6a367
Compare
3f6a367 to
245a33a
Compare
cmd/neofs-cli/modules/object/util.go
Outdated
| verb = sessionv2.VerbObjectDelete | ||
| // For DELETE, create context with two verbs: | ||
| // 1. DELETE for the deleted object | ||
| // 2. PUT for the tombstone |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meaning of OID for DELETE is to represent deleted OID.
| if err != nil { | ||
| return fmt.Errorf("get current block count: %w", err) | ||
| } | ||
| bh, err := cp.cnrClient.Morph().GetBlockHeader(idx - 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IR is subscribed to headers, it should have this data somewhere.
pkg/services/container/server.go
Outdated
| if err != nil { | ||
| return token, fmt.Errorf("get FS chain block count: %w", err) | ||
| } | ||
| header, err := s.GetBlockHeader(idx - 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SN also has this data from the latest header. Doing header lookups per-request is too costly.
internal/crypto/object.go
Outdated
| } | ||
| case neofscrypto.N3: | ||
| if sessionToken != nil { | ||
| if sessionToken != nil || sessionTokenV2 != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imagine a v2 token signed for some NNS names and one account signing something with it. It can be contract-based. This couldn't happen with v1 token, but for v2 it's totally possible.
| origin = origin.Origin() | ||
| } | ||
|
|
||
| neoPub, err := keys.NewPublicKeyFromBytes(key, elliptic.P256()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be an N3 signature at any step of v2 chain.
|
|
||
| func (b Service) verifySessionTokenV2AgainstRequest(token sessionSDKv2.Token, reqVerb sessionSDKv2.Verb, reqCnr cid.ID, reqObj oid.ID) error { | ||
| // When we PUT a tombstone, the requested object is not zero, | ||
| // but the session is not bound to it because the user cannot predict its ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something has to substitute it for associated ID above. IIRC this was the case once upon a time for v1 tokens.
245a33a to
a5ef555
Compare
Set subjects to default session token from `session-subjects` and `session-subjects-nns` flags for put, delete and lock operations. Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Signed-off-by: Andrey Butusov <andrey@nspcc.io>
1936daf to
9a6fcc8
Compare
Check new session tokens in inner ring container processors. Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Check container requests with new v2 session tokens, verify them using the nns resolver. Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Check object requests with new v2 session tokens, verify them using the nns resolver. Pass the v2 session token through the slicer, set them to the object session token, and authorize objects using the token. Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Refs nspcc-dev/neofs-api#350, nspcc-dev/neofs-sdk-go#750