Skip to content

[DO NOT MERGE] Handle cross repository mount #9582

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

Closed

Conversation

miminar
Copy link

@miminar miminar commented Jun 27, 2016

During a push with a cross-repo mount, authorize only against target
repository, not against source repository.

In OpenShift we allow to pull any blob stored in the registry as long as
the user is authorized to pull from repository he requested.

Closes #9540
Not sure whether #6841 is close-able with this. The issue mentions proper association of credentials with repositories (and especially the remote once if a pull through is in play). I'll verify.

@miminar
Copy link
Author

miminar commented Jun 27, 2016

/cc @legionus @soltysh

[test]

@@ -90,7 +91,7 @@ var (
)

func newAccessController(options map[string]interface{}) (registryauth.AccessController, error) {
log.Info("Using Origin Auth handler")
log.Info("using Origin Auth handler")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why changing that, only errors start with small letter.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, most of the upstream log messages are lower-cased. In v2.4.1 it's 33 messages starting with upper-cased letter vs 81 starting with lower-cased (all log levels).

But ok, keeping the messages same won't do any harm. I'll lower-case the new messages though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is part of origin code in which the patterns I've mentioned apply.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is part of origin code in which the patterns I've mentioned apply.

Yes, but the message appears only in registry's logs. Another reason for having registry in its own repository 😄.

@soltysh
Copy link
Contributor

soltysh commented Jun 27, 2016

Nits, but overall LGTM.

@legionus
Copy link
Contributor

LGTM

@soltysh
Copy link
Contributor

soltysh commented Jun 27, 2016

LGTM, squash and you're good to go.

@miminar miminar force-pushed the cross-repo-push-registry-fix branch from ab83d21 to 7940966 Compare June 27, 2016 13:35
@miminar
Copy link
Author

miminar commented Jun 27, 2016

@soltysh thanks! squashed.

@miminar
Copy link
Author

miminar commented Jun 27, 2016

(I'd still rather wait for a clean pass though)

@soltysh
Copy link
Contributor

soltysh commented Jun 27, 2016

Your wish is my command! I'll merge once this turns green.

//
// This function always grants access in the first case because OpenShift registry treats all the local blobs
// as accessible once authorized to access given repository (target one).
func isCrossRepoMountFromSourceRepository(ctx context.Context, namespace, imageRepo, verb string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are we guaranteeing that the access check has already been performed on the imageRepo?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's upstream's responsibility to do auth check for both repositories (source and target). See here: https://github.com/openshift/origin/blob/master/Godeps/_workspace/src/github.com/docker/distribution/registry/handlers/app.go#L771. The source check is done first. The second check will decide whether the user is authorized to push.

@bparees
Copy link
Contributor

bparees commented Jun 27, 2016

i've added extended test requests for tests that i think were broken by the recent registry changes.

@miminar miminar force-pushed the cross-repo-push-registry-fix branch from 7940966 to c78781b Compare June 27, 2016 15:00
@@ -196,7 +197,7 @@ func (ac *AccessController) Authorized(ctx context.Context, accessRecords ...reg
}
verifiedPrune = true
default:
if err := verifyImageStreamAccess(ctx, imageStreamNS, imageStreamName, verb, osClient); err != nil {
if err := authorizeRepositoryAccess(ctx, imageStreamNS, imageStreamName, verb, osClient); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather see this loop be aware of access records being skipped because they appear to be cross-repository mounts... if we skip an access record for that reason, this loop should ensure it is paired with an authorized push access record check

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's reasonable, I'll change it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@liggitt
Copy link
Contributor

liggitt commented Jun 27, 2016

actually, if I understand this correctly, this would allow a client to do the following:

  1. push a manifest M referencing layers L1,L2,L3 where L1 is their own layer in their own namespace, and L2 and L3 are layers from other namespaces they do not have access to
  2. this code (even with the adjustments described so far) would appear to skip access checks for L2, and L3
  3. The user could then pull the manifest and get all three layers, including the ones they were not supposed to have access to

@miminar miminar force-pushed the cross-repo-push-registry-fix branch from c78781b to c823e8c Compare June 27, 2016 19:22
func (r *pullthroughBlobStore) Create(ctx context.Context, options ...distribution.BlobCreateOption) (distribution.BlobWriter, error) {
options = append(options, storage.WithRepositoryMiddlewareWrapper(
func(ctx context.Context, repo distribution.Repository, name reference.Named) (distribution.Repository, error) {
nameParts := strings.SplitN(name.Name(), "/", 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to artificially limit the segments to 2, or fail if they give us something with more than 2 segments?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're doing it the same way on most other places. And AFAIK upstream registry doesn't support more than 2 segments either. We could create a utility function to do this. But I wouldn't clobber this with such a refactor.

@miminar miminar force-pushed the cross-repo-push-registry-fix branch from c823e8c to 9892109 Compare June 27, 2016 19:34
@miminar
Copy link
Author

miminar commented Jun 27, 2016

I changed the behavior to the old one. Now the first auth check for source repository is skipped in the auth module. The auth check has been moved to repository middleware. If the check fails (most of the time), the registry falls back to a blob upload (sends 202 to client as documented upstream).

If we were doing both checks in the auth module, the registry would return unathorized which would cancel whole push.

For this, we need to propagate our middleware code to upstream blob store during a Create() call. Which is not possibly without modifying upstream code. This brings a dependency on distribution/distribution#1757 (and a carry patch). Feel free to push it upstream. The same patch is needed to allow remote layer federation for remote registries when dealing with v1 manifest schema.

This doesn't attempt to fix the cross-repo mount by checking for blob presence in source repository. The blob checking needs to be done at several other places. We should fix it together with #7792. Until then, let's keep the old behavior.

@openshift-bot
Copy link
Contributor

openshift-bot commented Jun 28, 2016

continuous-integration/openshift-jenkins/test Running (https://ci.openshift.redhat.com/jenkins/job/test_pr_origin/5501/)

@liggitt
Copy link
Contributor

liggitt commented Jun 28, 2016

rather than skipping errors during auth, what if we store ones that look like cross-mount errors in the context. then, in the repository impls, we can first check to ensure auth ran, then short-circuit any operations for a given repo if there were deferred errors. see #9593 for a quick POC.

that would make me a lot more comfortable deferring enforcement of some auth errors, and being confident that no API path was going to hit a repository interface method we didn't expect

@pweil-
Copy link

pweil- commented Jun 28, 2016

@smarterclayton

@miminar miminar force-pushed the cross-repo-push-registry-fix branch from 9892109 to fb49049 Compare June 28, 2016 16:56
@miminar miminar changed the title Handle cross repository mount [DO NOT MERGE] Handle cross repository mount Jun 28, 2016
@openshift-bot
Copy link
Contributor

Evaluated for origin test up to fb49049

Michal Minar added 2 commits June 28, 2016 19:22
…pper during cross-repo mounts

This allows to use pullthroughBlobStore middleware wrapper during a
cross-repository mount. This is an upstream part of fix to enable remote
layer federation for the push.

Signed-off-by: Michal Minar <[email protected]>
This allows us to:

- do additional authorization checks during cross-repo mount on source
  repository
- remote layer federation

Signed-off-by: Michal Minar <[email protected]>
@openshift-bot
Copy link
Contributor

openshift-bot commented Jun 28, 2016

continuous-integration/openshift-jenkins/testextended Running (https://ci.openshift.redhat.com/jenkins/job/test_pr_origin_extended/253/) (Extended Tests: core(images), core(builds))

@bparees
Copy link
Contributor

bparees commented Jun 28, 2016

[testextended][extended:core(images)]

@bparees
Copy link
Contributor

bparees commented Jun 28, 2016

(bot does not seem to respect two testextended tags in one comment?)

@openshift-bot
Copy link
Contributor

Evaluated for origin testextended up to 3199a57

@bparees
Copy link
Contributor

bparees commented Jun 28, 2016

[testextended][extended:core(builds)]

@liggitt
Copy link
Contributor

liggitt commented Jun 28, 2016

closing in favor of #9593

@liggitt liggitt closed this Jun 28, 2016
@miminar
Copy link
Author

miminar commented Jun 28, 2016

closing in favor of #9593

@miminar miminar deleted the cross-repo-push-registry-fix branch November 10, 2016 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Push regression with new registry
7 participants