Does anyone have experience with F# code in partial trust scenarios? As in, creating assemblies with [<AllowPartiallyTrustedCallers>]
?
I am working on a couple of projects that we need to be able to run in partial trust, and we have been trying to use Level 2 Security Rules (http://msdn.microsoft.com/en-us/library/dd233102.aspx). In practice for our self-contained assemblies this is easy - just put an attribute; but sometimes our assemblies reference third-party DLLs that are not annotated and assumed "SecurityCritical." This is where it gets "interesting."
Having worked with it for past couple of days there appears to be a serious issue with F#. .NET security policy expects you to annotate types/methods with [<SecuritySafeCritical>]
if they reference or call "SecurityCritical" code, which happens to be most of the code out there on NuGet because this is what it defaults to. Now, in F# this works ok until you start using closures. You cannot do:
namespace Foo
open System.Security
[<assembly: AllowPartiallyTrustedCallers>]
[<assembly: SecurityRules(SecurityRuleSet.Level2)>]
do()
[<SecurityCritical>]
module C =
let get () = [ 1 .. 10 ]
[<SecuritySafeCritical>]
module M =
let foo () =
seq {
for i in 1 .. 10 do
yield!
C.get ()
|> Seq.filter (fun x -> x % 2 = 0)
}
This assembly fails to pass SecAnnotate.exe
checks because F# compiler lifts the closure to a separate type, which is now NOT annotated with [<SecuritySafeCritical>]
, defaults to Transparent, but references some critical code, which is an error.
It sounds like a minor restriction but it cost me many hours altering code to avoid closures and satisfy SecAnnotate constraints. Maybe F# could propagate security attributes to closure types it creates? Is there another simple way around this that I am missing?