Page MenuHomePhabricator

Implement top-level "Spaces" that provide policy isolation to groups of objects
Closed, ResolvedPublic

Assigned To
Authored By
epriestley
Sep 11 2013, 8:48 PM
Referenced Files
None
Tokens
"Pterodactyl" token, awarded by cburroughs."Like" token, awarded by marceldegraaf."Love" token, awarded by johnny-bit."Like" token, awarded by bobek."Mountain of Wealth" token, awarded by nagym718."Like" token, awarded by flamingice."The World Burns" token, awarded by emanuelsan."Love" token, awarded by qgil."Love" token, awarded by jsavalle."The World Burns" token, awarded by allan.laal.

Description

This task is a wide-ranging discussion of providing policy containers for groups of objects. Use cases broadly include:

  • Restricting unprivileged users (like contractors or clients) to a small section of your install.
  • Creating privileged areas (like a "Security" space) that make it easier to restrict access to a lot of objects.

These containers are called "Spaces".

Spaces mostly don't do anything new, per se (you can do everything that Spaces allow by manually setting granular policies on individual objects), they just make it a lot easier to apply policies consistently across larger groups of objects, since it's painful and error-prone to manually edit large numbers of objects.

See the specs at T3820#116875

90% of the discussion on this task is out of date or not particularly relevant to the modern plans for Spaces.


Older Discussion

Until recently, I've sort of been operating under the assumption that when you tag an object with a project, we'll (in some cases) give it that project's policy ("Visible to: Members of project X") by default. But I'm not actually sure this makes much sense.

Some discussion in T2628.

The arguments for doing this are:

  • It makes it easier to set policies, since you just add a project instead of separately setting a project and a policy.
  • In some cases, it seems clearly correct (for example, a "Security" project should probably imply "Visible to: Security").

However, some arguments against it are:

  • Projects are one-to-many, but policies aren't really. Intersecting all the project policies is really complicated and computationally intensive, and probably not what anyone wants. An approach discussed in T2628 is having a "primary" project, but I think this is messy and confusing too.
  • To the degree that we have a "primary" project, this creates weirdness when you add a secondary project which normally sets policies -- we either prevent it (weird, feels arbitrary) or add it as non-primary project which doesn't affect policies (confusing, also feels arbitrary).
  • Subprojects potentially become kind of a nightmare.
  • It's not very explicit.
  • I think the "Security" case is a weird edge case, and most projects in most use cases shouldn't imply policies. Broadly, most interest in policies from users is very broad ("users in group X can/can not access entire application Y"). The "Security" case is nice-to-have, but I don't think anyone's actually ever asked for it.

So maybe for v1 we just separate policies from projects completely, and putting something in a project never implies a policy. You can set a policy manually, and otherwise we focus on getting coarse-grained policies and policy defaults correct as often as possible.

For v2, if there's enough feedback, we can work on ways to make projects imply policies. Some thoughts are:

  • The project control could make it easy to set the policy to "Visible to: one of the projects you typed".
  • The project control could auto-update and prompt you to "Set this project to 'security'?" when you add that project.
  • When you add "Security", we could give you a modal prompt.
  • When you add "Security", we could hard-add it to the policy constraints as an intersect.

All of these would probably be based on flags on the projects, and these flags would probably be quite rare, since they're only necessary for secret-ish projects.

I'd guess that these default-allow policies will actually be rarer than default-deny policies (e.g., "users shouldn't be able to see anything, except users in group Y can see stuff in project Y"). A case here is clients who you might want to give logins to but shut out of everything except stuff related to their projects.

So maybe we eventually end up with a couple classes of projects:

  • Normal projects, with no policy implications. These are the vast majority of projects.
  • Projects with a soft or hard "intersect" implication, like "Security". Adding these projects excludes non-members, essentially setting the policy to "<The Existing Policy> AND is a member of Security".
  • Projects with a soft or hard "union" implication, like "Client X". Adding these projects includes members, essentially setting the policy to "<The Existing Policy> OR is a member of Client X".

Exactly how hard/soft those implications are is then a UI/UX thing? Does this seem kind of reasonable?

Related Objects

StatusAssignedTask
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
OpenNone
Openepriestley
Resolvedepriestley
ResolvedNone
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley
OpenNone
Resolvedepriestley
Resolvedepriestley
Resolvedepriestley

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

We'll allow namespace moves. The "global" namespace will just sort of be a default (and a namespace for existing objects to get put into when we build this), and not very special in other respects.

Would you be able to give a rough estimate for paid prioritization of this task?

Very roughly I'd guess this is somewhere in the 80-120 hour range. D9204 is a very bare-bones technical implementation which attempts to show that the feature is possible, but this needs a great deal of product and integration work on top of that.

epriestley renamed this task from Build JIRA-like "Namespaces" for putting global, default-deny walls around groups of unprivileged users to Implement top-level "Spaces" that provide policy isolation to groups of objects.Apr 11 2015, 9:02 PM
epriestley updated the task description. (Show Details)

In concrete terms, major items here that we know about specifically are:

New "Spaces" Application

  • New top-level application for creating, managing, and reviewing Spaces.
    • Administrators can create, configure, and set policies for spaces in this application.
    • Users can review spaces in detail.
  • Mostly exists in D9204, but needs to be modernized since it's just over a year old now.

New PhabricatorSpacesInterface Interface

  • New interface which defines objects that exist in Spaces.

Enforcing Policy Rules

  • Objects which implement the PhabricatorSpacesInterface should have policy rules enforced by the policy layer.
  • To enforce rules, the Viewer needs to carry information about access to spaces.
  • This is the most complex, security-sensitive part of the implementation.
  • This probably interacts with (and is blocked by) T7703.
  • This probably interacts with (and is blocked by) T6367.
  • (I have a small amount of very old code for this locally.)

UX: Putting Objects in Spaces

  • Objects which support spaces get a new "Space:" control on their edit forms.
  • This can be a <select /> for now but probably needs more sophisticated design and interactions later. Particularly, it is likely to eventually be a common control that users will rarely interact with directly, so finding a way to integrate it into form design may eventually be desirable.
  • Objects which support spaces need new core transactions for setting and changing spaces.

UX: Finding Objects in Spaces

  • ApplicationSearch needs to support spaces in a builtin way so users can search for objects in (or not in) specific spaces.
  • This can be a typeahead for now, but likely needs more sophisticated interaction design in the long run, as it faces the same forces (ubiquity but rare use) that the edit control does.
  • Objects which support spaces need core query support. This is the most performance-sensitive part of the implementation, although I believe it is not especially complex.
  • This probably interacts with (and is at least partially blocked by) T7715.

UX: Switching Between Spaces

  • Provide users with access to multiple spaces a way to choose which space objects are created into by default.
  • This probably looks like a new global menu:
+---+
| S |
+---+---------------+
|   General Stuff   |
| * Secret Stuff    |
|   Security Stuff  |
+-------------------+
  • This selector may also affect which spaces are shown by default, or have separate controls for selecting that.
  • This might be overkill, and maybe the "Space:" control just ends up controlling this interaction (e.g., has a "Set Default..." option).

UX: Understanding Object Spaces

  • Object detail pages and search result lists need to communicate space information to viewers.
  • Object references and embeds, too.
  • Likely also some CLI interfaces in arcanist.
  • This is primarily a design issue. We generally have enough information when rendering these elements to figure out the values automatically, but accommodating them gracefully may be complicated in some cases (particularly on list views).

UX: No Spaces

  • When a user has access to only one space, we may want to degrade some of the UI.
  • This is primarily a design/interaction issue. Ideally, we can design this UI so that it stays out of the way and we can always show it, but that may be impractical or confusing. Of course, hiding it also risks confusion and reduces discoverability. We'll need to strike some balance here.

Space Support in Applications

  • Once all the infrastructure works, we need to implement it all the applications.
  • We don't need to do them all at once, and hopefully the infrastructure makes this relatively straightforward, but the most interesting applications (Maniphest) are likely also the most complicated.

Additional Behaviors

  • We may want to introduce specialized rules around moving objects between spaces; some discussion earlier. The path forward here probably won't be clear until
  • Some applications have reasonable integration points outside of direct space support: Herald conditions and Policy rules to name two.

Documentation

  • We should write some documentation about this.

That roughly breaks out like this:

EstimateRequiredSummaryDescription
4 HoursRequiredSpaces ApplicationModernize and land "Spaces" application.
0 HoursRequiredSpaces InterfaceLand PhabricatorSpacesInterface.
6 HoursRequiredTechnical BlockerClear T7703 to support policy interaction.
6 HoursRequiredTechnical BlockerClear T6367 to support policy interaction.
4 HoursRequiredPolicy RulesEnforce policy rules for objects which support Spaces.
4 HoursRequiredEdit UIAllow objects to be put in spaces.
8 HoursPartially RequiredTechnical BlockerClear however much of T7715 stands in the way of clean ApplicationSearch integration.
4 HoursRequiredSearch UIProvide ApplicationSearch integration.
4 HoursRequiredSwitching UIUI for controlling space defaults.
4 HoursRequiredUI IntegrationUI for understanding which spaces objects belong to.
2 HoursProbably RequiredSimplified UISimplify UX for users with access to only one space.
4 HoursRequiredInitial IntegrationIntegration into a simple application (likely Paste).
8 HoursRequiredManiphestIntegration into Maniphest.
About 2 Hours EachOptionalOther ApplicationsIntegration into other applications, as desired.
TBDOptionalOther BehaviorsSecondary integrations and behaviors.
1 HourRequiredDocumentationDocument spaces.

Total Known, Required Work: 59 Hours

I imagine that "Other Behaviors" is likely to have a nontrivial amount of work (e.g., around the "Security Dropbox" use case), and that we'll run into some issues and blockers I haven't anticipated, but that's my best guess at the timeline and main build process for the feature's core.

Objects which support spaces get a new "Space:" control on their edit forms.

That sounds like a poor field name for users...

Also, just to be clear, it would be possible for any user to create an object in any space and still have access to the object without regard to the whole space's policies right? And also it would be possible for you to bring in specific people on specific objects without giving them access to the entire space?

That sounds like a poor field name for users...

Sure. It won't necessarily be called "Space" or be a field at all, I just mean that we'll have some control for users to choose which space an object belongs to when editing it.

Also, just to be clear, it would be possible for any user to create an object in any space and still have access to the object without regard to the whole space's policies right?

No. Spaces will have policy rules like other objects, so users will not necessarily be able to see all Spaces. Users will not be able to create an object in a Space they can't see.

For example, it will be possible to create a totally secret Space like "The Inner Cabal" which only a few users can see. Other users will not be able to see that this Space exists, or see anything inside it.

And also it would be possible for you to bring in specific people on specific objects without giving them access to the entire space?

Not per se. Users will never be able to see objects in a Space they can't see.

I'm intentionally leaving the "Security Dropbox" use case relatively undefined in the "Known Work" scoping above, and lumping it into "Other Behaviors". It would likely work like this:

  • The "Security" space is visible to all users.
  • Unlike a normal space, where the policy implied by space membership is "Can see the space, and <other policies>", the "Security" space is a special space that has an explicit policy, like "Is member of SecurityProject and <other policies>".
  • We punch a hole through it:

However, I can imagine other variants of this and possibly that this is just how all Spaces work if the default implied policy isn't as good or useful as I anticipate it being, although the default behavior is desirable as the common case from an efficiency point of view.

Spaces are structurally positioned to satisfy this use case and I think it's a reasonable one and plan to support it in the upstream, I'm just not yet sure exactly which combination of approahces we'll use to support it and probably won't be able to commit to a specific approach until the core is built and we have a better sense that most of the assumptions here are pretty reasonable and don't need major changes.

The description posted above looks like a good first version.

Krenair's question refers to a main use case in Wikimedia, open source projects in general, and probably more:

  1. Regular user reports a bug in Space:Public.
  2. Turns out that this is a security bug, and it is moved to Space:Security, where only the Security team has view & edit permissions.

or

  1. Regular user reports a bug in Space:Security, where regular users can only access to report bugs but not see/edit anything.

Will the Security team have a way to allow the reporter and other experts CCed to keep viewing, editing, and commenting in that specific task, without granting permissions to access anything else in Space:Security?

If so, then Spaces would cover this feature that now is provided by our local Security extension. If not, then Spaces would bring a regression, and we would need to keep our Security extension for a longer time, which is what we want to avoid by funding the feature set described above.

PS: I like "Space:General", "Space:Security", "Space:Procurement" and I think users will get this concept. I'm saying this with my humble community management & product marketing hats.

Oh, and about applications, Maniphest sure, followed by Files, then Mockups, perhaps. Paste... maybe.

Differential and code related friends are not interesting for the Wikimedia case.

epriestley claimed this task.

Spaces are now available in master. They'll promote to stable in this week's release, and are likely to leave prototype next week.

You can find some documentation here: https://secure.phabricator.com/book/phabricator/article/spaces/

T8376 has details and additional context, as well as links to remaining work.

We have a similar use case as Wikimedia's. We want the security team to CC people on tasks in Space:Security so that the CC'd people have viewing, editing, and commenting permissions, but don't have access to anything else in Space:Security. Is that possible?

We'd also like to make tasks tagged with certain projects automatically be put in a certain space, e.g. tagging a task with Project:PrivacyPolicy puts that task in Space:Restricted. Is something like that possible?

We have a similar use case as Wikimedia's. We want the security team to CC people on tasks in Space:Security so that the CC'd people have viewing, editing, and commenting permissions, but don't have access to anything else in Space:Security. Is that possible?

No, Spaces can't support this use case because Space boundaries are absolute. You can find some discussion in T8434. See also T4411. At HEAD, it is possible to define a "CCs + Security Team" object policy, see objects related to T8434.

We'd also like to make tasks tagged with certain projects automatically be put in a certain space, e.g. tagging a task with Project:PrivacyPolicy puts that task in Space:Restricted. Is something like that possible?

No. It's an explicit product decision that projects never affect policies: I think it's too hard to understand and communicate what will happen if an object is tagged with several projects which each have policy effects.

The general direction of exploration in T8434 is making Maniphest more flexible around providing modal creation workflows, where you "File a Security Task" instead of "File a Task + fiddle with options", although the WMF use case also has some subtlety to it.

Spaces have been working great for my install. The only real place where they're lacking I think arises from their coarseness/mutual-exclusivity.

My root issue is that I have teams A, B, C who mostly work disjointly but sometimes collaborate. It's hard for me to use Spaces for that as I'd need the power set of {A,B,C}, and of course in reality it's more than just 3 groups.

For v2, if there's enough feedback, we can work on ways to make projects imply policies.

That feels like it would address my issue, although I wouldn't presume to claim this is the appropriate way.

Right now I can roughly approximate a solution my issue having a project for each of A, B, and C and setting maniphest's default visibility to "Subscribers". Then I can subscribe any of A, B, and C as needed. This is mostly fine, but there are two negatives:

  • I have to duplicate tagging and subscribing. Whenever I add A to a task's projects, I have to also remember to subscribe A
  • It's a subscribe action vs just a policy change. I often prefer to just make the task visible to A without necessarily subscribing the whole A team.

If projects could carry policy, I would instead ideally make my default visibility "Members of any of this task's projects" and then I could add or remove projects as needed.

That all being said, I have read through /book/phabricator/article/projects/#policies-in-depth and those concerns are valid. I think some of them are not huge issues in that if you're opting into the non-default "Any of attached projects" or "All of attached projects", then you've asked for something pretty directly. I also don't have personally have a need for a "Security"/lockdown-style project, but I would argue that Spaces as they exist are already a good model for that.