diff --git a/docs/project/list-of-obsoletions.md b/docs/project/list-of-obsoletions.md
new file mode 100644
index 0000000000000..5083069cb799d
--- /dev/null
+++ b/docs/project/list-of-obsoletions.md
@@ -0,0 +1,17 @@
+List of Obsoletions
+==================
+
+Per https://github.com/dotnet/designs/blob/master/accepted/2020/better-obsoletion/better-obsoletion.md, we now have a strategy in place for marking existing APIs as `[Obsolete]`. This takes advantage of the new diagnostic id and URL template mechanisms introduced to `ObsoleteAttribute` in .NET 5.
+
+When obsoleting an API, use the diagnostic ID `MSLIB####`, where _\#\#\#\#_ is the next four-digit identifier in the sequence, and add it to the list below. This helps us maintain a centralized location of all APIs that were obsoleted using this mechanism.
+
+The URL template we use for obsoletions is `https://aka.ms/dotnet-warnings/{0}`.
+
+Currently the identifiers `MSLIB0001` through `MSLIB0999` are carved out for obsoletions. If we wish to introduce analyzer warnings not related to obsoletion in the future, we should begin at a different range, such as `MSLIB2000`.
+
+## Current obsoletions (`MSLIB0001` - `MSLIB0999`)
+
+| Diagnostic ID | Description |
+| :--------------- | :---------- |
+| __`MSLIB0001`__ | (Reserved for `Encoding.UTF7`.) |
+| __`MSLIB0002`__ | `PrincipalPermissionAttribute` is not honored by the runtime and must not be used. |
diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset
index 66a6af943a1ef..0a84dcdbdffd9 100644
--- a/eng/CodeAnalysis.ruleset
+++ b/eng/CodeAnalysis.ruleset
@@ -126,7 +126,8 @@
-
+
+
diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs
index d561bdfab3728..7cfd44259d70e 100644
--- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs
+++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs
@@ -1128,6 +1128,9 @@ public void FromXml(System.Security.SecurityElement elem) { }
[System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public sealed partial class PrincipalPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute
{
+#if CAS_OBSOLETIONS
+ [System.ObsoleteAttribute("PrincipalPermissionAttribute is not honored by the runtime and must not be used.", true, DiagnosticId = "MSLIB0002", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
+#endif
public PrincipalPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { }
public bool Authenticated { get { throw null; } set { } }
public string Name { get { throw null; } set { } }
diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj
index 7d70b43e941c5..ec7d4c444af70 100644
--- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj
+++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.csproj
@@ -1,13 +1,15 @@
$(NetCoreAppCurrent);netstandard2.0;net461;netcoreapp3.0;$(NetFrameworkCurrent)
- true
true
true
+
+ $(DefineConstants);CAS_OBSOLETIONS
+
diff --git a/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj b/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj
index 174f60d9b0688..ab56a608e193c 100644
--- a/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj
+++ b/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj
@@ -2,9 +2,11 @@
true
$(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461;$(NetFrameworkCurrent)
- true
true
+
+ $(DefineConstants);CAS_OBSOLETIONS
+
diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs
index 28ef1a2705a1a..cbf5ac54ade29 100644
--- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs
+++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs
@@ -7,6 +7,9 @@ namespace System.Security.Permissions
[AttributeUsage((AttributeTargets)(68), AllowMultiple = true, Inherited = false)]
public sealed partial class PrincipalPermissionAttribute : CodeAccessSecurityAttribute
{
+#if CAS_OBSOLETIONS
+ [Obsolete("PrincipalPermissionAttribute is not honored by the runtime and must not be used.", error: true, DiagnosticId = "MSLIB0002", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
+#endif
public PrincipalPermissionAttribute(SecurityAction action) : base(default(SecurityAction)) { }
public bool Authenticated { get; set; }
public string Name { get; set; }
diff --git a/src/libraries/System.Security.Permissions/tests/PermissionTests.cs b/src/libraries/System.Security.Permissions/tests/PermissionTests.cs
index 8494d5c2328d3..5ab5d595cf506 100644
--- a/src/libraries/System.Security.Permissions/tests/PermissionTests.cs
+++ b/src/libraries/System.Security.Permissions/tests/PermissionTests.cs
@@ -210,13 +210,6 @@ public static void PrincipalPermissionCallMethods()
pp.ToXml();
}
- [Fact]
- public static void PrincipalPermissionAttributeCallMethods()
- {
- PrincipalPermissionAttribute ppa = new PrincipalPermissionAttribute(new Permissions.SecurityAction());
- IPermission ip = ppa.CreatePermission();
- }
-
[Fact]
public static void PublisherIdentityPermissionCallMethods()
{