Skip to content
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

[Family Safety API] Official API Review #3036

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions specs/FamilySafety.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
Family Safety
===

# Background
Our customers have asked for a new API to toggle the Family Safety feature on and off. The Family
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the value is locked once the browser process starts, I think "toggling" is overselling the feature. You can't toggle it. You can merely choose whether to enable it or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please fix. Replace with 'enable'

Safety feature is enabled or disabled for a browser process instance, and the end developer
won't be able to change it while the webview2 browser process instance is running. Once enabled,
it will provide the same functionally as the browser Family Safety feature including: Activity
reports, search filtering, and web filtering. Besides toggling the feature, we also provide an
API to add desired sites to the allowed uris, so app functionality will not be impacted by
Family Safety. Additionally, parents can also override a block.
Please see https://www.microsoft.com/en-us/microsoft-365/family-safety for details on Family Safety.

# Examples
## WinRT and .NET
```c#
void CreateEnvrionmentWithOption()
Copy link
Contributor

Choose a reason for hiding this comment

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

TYPO

Suggested change
void CreateEnvrionmentWithOption()
void CreateEnvironmentWithOption()

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, please fix.

{
// If parents set filtering rules to only allowed sites. App developers can use
// FamilySafetyAllowedUris to show app content and still honor general filter settings set
// by parents.
CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions();
options.IsFamilySafetyEnabled = true;
// appassets.example is used as an example app content. All subdomain are added to the allow list
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment here does not match comment in IDL. Which is correct?

Comment here implies that https://subdomain.appassets.example/ is allowed (subdomain). But the comment in IDL does not mention subdomains. It says that * is a wildcard, which therefore matches paths under the appassets.example domain, but not subdomains.

To clarify, given the pattern https://appassets.example/*, which of the following URIs are allowed?

URI Allowed?
https://subdomain.appassets.example/
https://subdomain.appassets.example/path
https://appassets.example/
https://appassets.example/path
http://appassets.example/
http://appassets.example/path

If the comment in the IDL is correct, then there doesn't appear to be a way to securely match subdomains, because the * can match slashes too: https://*.appassets.example/ will inadvertently match https://hackersite.example/attack.appassets.example/.

Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is out of date. There is no good way to match subdomains with this.

options.FamilySafetyAllowedUris.Add("https://appassets.example/*");
auto environment = await CoreWebView2Environment.CreateAsync(BrowserExecutableFolder, UserDataFolder, options);
}
```
## Win32 C++
```cpp
HRESULT InitializeWebView()
{
// If parents set filtering rules to only allowed sites. App developers can use
// FamilySafetyAllowedUris to show app content and still honor general filter settings set
// by parents.
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
options->put_IsFamilySafetyEnabled(TRUE);
// appassets.example is used as an example app content. All subdomain are added to the allow list
const WCHAR* allowedUris[1] = {L"https://appassets.example/*"};
options->SetFamilySafetyAllowedUris(1, allowedUris);
Copy link
Contributor

Choose a reason for hiding this comment

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

When family safety is enabled, isn't there a list of sites to allow/block in the family account already? Is Get returning that cloud information, or is this a local-override that's merged with the cloud values?

Copy link
Contributor

Choose a reason for hiding this comment

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

My interpretation is that this list is merged with the cloud-controlled values. Maybe call this FamilySafetyAdditionalAllowedUris? The word "Additional" already is in use in this class for a similar concept (AdditionalBrowserArguments).

Copy link
Contributor

Choose a reason for hiding this comment

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

Local only. There is no developer access to the family safety's cloud list. Parent explicit block list wins over this local allow list.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's rename: FamilySafetyAdditionalAllowedUris

HRESULT hr = CreateCoreWebView2EnvironmentWithOptions("", nullptr, options.Get(),
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
this, &AppWindow::OnCreateEnvironmentCompleted)
.Get());
}
```

# API Details
```
interface ICoreWebView2EnvironmentOptions3;

/// Additional options used to create WebView2 Environment.
[uuid(D0965AC5-11EB-4A49-AA1A-C8E9898F80AF), object, pointer_default(unique)]
interface ICoreWebView2EnvironmentOptions3 : IUnknown {
/// `IsFamilySafetyEnabled` property is to enable/disable family safety feature.
/// It is `FALSE` by default.
/// When `IsFamilySafetyEnabled` is `TRUE` WebView2 provides the same Family Safety
/// functionality as the Edge browser.
/// Family Safety is a set of features available on Windows for managing children Internet
/// priviliges. Microsoft account may be linked to have a family relationship, with adults
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// priviliges. Microsoft account may be linked to have a family relationship, with adults
/// privileges. Microsoft account may be linked to have a family relationship, with adults

Overall, this comment block could do with an editing pass.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please fix typo.
Please revise paragraph or ask for PM to help rephrase.

/// and children. Adults have certain managements options over the children in their family,
/// where each option is applied per-child. Edge browser provide the following options:
/// Activity reporting, Web filtering and SafeSearch. Please see
/// https://aka.ms/EdgeFamilySafetyFeatureOverview for more details on each feature.
[propget] HRESULT IsFamilySafetyEnabled([out, retval] BOOL* value);
/// Sets the `IsFamilySafetyEnabled` property.
[propput] HRESULT IsFamilySaFetyEnabled([in] BOOL value);

/// `GetFamilySafetyAllowedUris` and `SetFamilySafetyAllowedUris` allow developers to get and set
/// the list of URIs that will be allowed by the Family Safety filter even when in Block All mode.
/// Family Safety provides web filtering control in two modes: Allow-all and Block-all. In
Copy link
Contributor

Choose a reason for hiding this comment

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

How do the allow-all and block-all modes relate to this API? Is block-all another way of saying IsFamilySafetyEnabled==true?

Copy link
Contributor

Choose a reason for hiding this comment

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

Here's my interpretation:

IsFamilySafetyEnabled Block mode Result
False * All URIs are allowed
True Allow-all Parent provides list of block URIs; anything unknown is allowed
True Block-all Parent provides list of allowed URIs; anything unknown is blocked

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good table we should include in our documentation:

| IsFamilySafetyEnabled | Family Safety Default Block Mode | Result |
| --- | --- | --- |
| `False` | * | All URIs are allowed |
| `True` | Allow by default | Parent provides list of block URIs; anything unknown is allowed | 
| `True` | Block by default | Parent provides list of allowed URIs; App provides FamilySafetyAdditionalAllowedUris list of additional allowed URIs; anything unknown is blocked |

Also, please ensure this documentation to describe in words what the table says esp including how FamilySafetyAdditionalAllowedUris interacts with it.

/// Allow-all mode, only sites that are blocked by the parents will be blocked. In
Copy link
Contributor

Choose a reason for hiding this comment

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

Where's the API to block a site?

Copy link
Contributor

Choose a reason for hiding this comment

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

Out of scope for this feature.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please ensure documentation makes it clear that this is about enabling family safety to respect OS family safety settings and not to configure family safety specific to your app, other than the additional allowed URI list which is just to ensure the app can work with family safety.

/// blocked-all mode, only allowed sites that are allowed by the parents are allowed. In this
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// blocked-all mode, only allowed sites that are allowed by the parents are allowed. In this
/// block-all mode, only allowed sites that are allowed by the parents are allowed. In this

Copy link
Contributor

Choose a reason for hiding this comment

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

Please fix

/// scenario, apps using WebView2 will have their content blocked if enabled Family Safety in WebView2.
Copy link
Contributor

Choose a reason for hiding this comment

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

"In this scenario" - which scenario are we talking about? The allow-all scenario or the block-all scenario?

Copy link
Contributor

Choose a reason for hiding this comment

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

Please revise this paragraph.

/// Please see https://aka.ms/EdgeFamilySafetyContentFiltering for more details.
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment text implies that this list of allowed URIs is ignored in allow-all mode.

What happens if Family Safety is in allow-mode, parent has blocked https://example.com/, and the app adds https://example.com/ to the FamilySafetyAllowedUris? Who wins - the app or the parent? The comment above implies that the parent wins, and the URIs are blocked. Is there a way for the app to detect this case, so it knows that the app will not be functional and can provide a better error message? Or does the app just have to navigate to its home page, observe the navigation error, and try to guess whether the navigation failure was due to Family Safety (as opposed to a network or server error).

If the app wins, then maybe call this FamilySafetyAlwaysAllowedUris (the "always" implying that this overrides parent settings).

Copy link
Contributor

Choose a reason for hiding this comment

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

The comment is correct: the parent list wins.

Additionally, we need to document what happens when Family Safety blocks a website (auto navigated to the Family Safety site), and recommendations on Family Safety websites that need to be allowed in order for this all to work.

///
/// The `uris` parameter value are list of uris that is a wildcard string matched aganist the
/// navigation uri. This is a glob style wildcard string in which a `*` matches zero or more characters and
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 use this syntax anywhere else? Is this following some kind of existing practice?

Copy link
Contributor

Choose a reason for hiding this comment

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

Same format is used by custom scheme registration AllowedOrigins and AddWebResourceRequestedFilter. The latter has a big fancy table.

Documentation should probably say "using the same format as AddWebResourceRequestedFilter" and link to that page, so developers can reach the big fancy table.

Copy link
Contributor

Choose a reason for hiding this comment

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

I will open an ADO item to make a new doc concepts page for this matching syntax that we can link to from here.

Before then, we can have this documentation just do a brief one sentence summary and link to the AddWebResourceRequestedFilter page and say to follow the guidance for its syntax details.

/// `?` matches exactly one character.
/// These wildcard characters can be escaped using a backslash just before
/// the wildcard character in order to represent the literal `*` or `?`.
///
/// | URI Example | Navigation URI | Match | Notes |
/// | ---- | ---- | ---- | ---- |
/// | `https://example.com/a/b/c` | `https://exmaple.com/a/b/c` | Yes | Matches exact uri |
/// | `*` | `https://example.com/a/b/c` | Yes | A single * will match all URIs |
/// | `https://example.com/*` | `https://exmaple.com/a/b/c` | Yes | Matches everything in example.com |
/// \snippet AppWindow.cpp CoreWebView2FamilySafety
HRESULT GetFamilySafetyAllowedUris([out] UINT32* uriCounts, [out] LPWSTR** uris);
/// Set the family safety allowed URIs. See GetFamilySafetyAllowedUris for more information.
HRESULT SetFamilySafetyAllowedUris([in] UINT32 urisCount, [in] LPCWSTR* uris);
}
```

```c# (but really MIDL3)
namespace Microsoft.Web.WebView2.Core
{
// ...
runtimeclass CoreWebView2Environment
{
// ...

[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2EnvironmentOptions3")]
{
// ICoreWebView2EnvironmentOptions3 members
Boolean IsFamilySafetyEnabled { get; set; };
Copy link
Contributor

Choose a reason for hiding this comment

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

For both APIs we want to remove brand names and use generic term "Parental Controls":

IsFamilySafetyEnabled becomes:

  • AreParentControlsEnabled

FamilySafetyAllowedUris becomes:

  • ParentalControlsAdditionalAllowedUris

But continue to use Family Safety in the documentation.


// List of allowed uris
IVector<String> FamilySafetyAllowedUris { get; };
}
}
}
```