Default Policy Implementation and Policy File Syntax

Last Modified: 30 October, 1997

The policy for a Java runtime (specifying which permissions are available for code from various principals) is represented by a Policy object. More specifically, it is represented by a Policy subclass providing an implementation of the abstract methods in the Policy class (which is in the java.security package).

The source location for the policy information utilized by the Policy object is up to the Policy implementation. There is a default Policy implementation that obtains its information from static policy configuration files. The rest of this document pertains to the default Policy implementation and the syntax that must be used in policy files it reads.

Here is an outline:

Default Policy Implementation
Changing the Policy Implementation
Policy File Syntax
Policy File Examples

Default Policy Implementation

In the default Policy implementation, the policy is represented as one or more separate persistent configurations. In this default implementation, each Java runtime may have one system policy file and one user policy file.

The system policy file is by default located at

    <java.home>/lib/security/java.policy

where <java.home> indicates the JDK installation directory (determined by the value of the "java.home" system property). Note: the name of the system policy file can be changed by resetting the value of the security property named "policy.java" to the new name.

The user policy file is by default located at

    <user.home>/.java.policy

where <user.home> indicates the user's home directory (determined by the value of the "user.home" system property). However, if the user is running a program invoked with the -D switch specifying a "java.policy" value, as in:

    java -Djava.policy="myPolicyFileName" MyClass
then the name in quotes following "-Djava.policy=" is used as the name of the user policy file. It can include the path; otherwise, the file is assumed to be in the current directory.

The default Policy object is initialized the first time its evaluate method is called, or whenever its refresh method is called. Initialization involves parsing the policy configuration file(s) (see Policy File Syntax), and then populating the Policy object. It loads in the system policy first, then adds to it the user policy. If neither policy is present, a built-in policy equivalent to the original sandbox policy is used.

Changing the Policy Implementation

The default Policy implementation can be changed to a different class. This is done by editing the security properties file, which is the java.security file in the lib/security directory of the JDK. Thus, if the JDK is installed in a directory called jdk1.2, the file would be jdk1.2/lib/security/java.security.

One of the types of properties you can set in java.security is of the following form:

    policy.provider=PolicyClassName

PolicyClassName must specify the fully qualified name of the desired Policy implementation class.

Suppose for example that the Policy implementation class is COM.acme.Policy. Then add the following line to the java.security file:

    policy.provider=COM.acme.Policy

Policy File Syntax

The policy configuration file(s) for a JDK installation specify what permissions (which types of system resource accesses) are allowed by code from specified code sources.

In order for an applet (or an application running under a Security Manager) to be allowed to perform secured actions (such as reading or writing a file), the applet must be granted permission for that particular action. In the default Policy implementation, that permission must be granted by a code source entry in a policy configuration file. (See below and the "Java Security Architecture Specification" for more information.)

Code being executed is always considered to come from a particular "code source". The code source includes not only the location (URL) where the applet originated from, but also a reference to the public key corresponding to the private key used to sign the code. Public keys in a code source are referenced by (symbolic) alias names from the user's keystore, located in the file named ".keystore" in the user's home directory. See the keytool (for Solaris) (for Windows) documentation for more information about the keystore.

In a policy configuration file, a code source is represented by two components: a code base (URL), and an alias name (preceded by "signedBy"), where the alias name identifies the keystore entry containing the public key that must be used to verify the signature on the JAR file.

Each policy file consists of one or more "grant entries", each of which consists of a number of "permission entries". Each grant entry grants a specified code source a set of permissions, specifying which actions are allowed. The basic format of a grant entry is the following:

  grant signedBy "alias", codeBase "URL" {
    permission Type "name", "action", 
        signedBy "alias";
    ....
    permission Type "name", "action", 
        signedBy "alias";
  };
 	
All non-italicized items above must appear as is (although case doesn't matter and some are optional, as noted below). Italicized items represent variable values.

A grant entry must begin with the word grant. The signedBy and codeBase name/value pairs are optional. If they are not present, then any signer (including unsigned code) will match, and any codeBase will match.

A permission entry must begin with the word permission. The word Type in the template above would actually be a specific permission type, such as java.io.FilePermission or java.lang.RuntimePermission.

The "action" is required for many permission types, such as java.io.FilePermission (where it specifies what type of file access is permitted). It is not required for categories such as java.lang.RuntimePermission where it is not necessary - you either have the permission specified by the "name" value following the type name or you don't.

The signedBy name/value pair for a permission entry is optional. If present, it indicates a signed permission. That is, the permission class itself must be signed by the given alias in order for the permission to be granted. For example, suppose you have the following grant entry:

  grant {
    permission Foo "foobar", signedBy "FooSoft";
  }

Then this permission of type Foo is granted if the Foo.class permission has been signed by the "FooSoft" alias, or if Foo.class is a system class (i.e., is found on the CLASSPATH), since classes on the CLASSPATH currently cannot be signed and are not subject to policy restrictions.

Items that appear in a permission entry must appear in the specified order (permission, Type, "name", and "action"). An entry is terminated with a semicolon.

Case is unimportant for the identifiers (permission, signedBy, codeBase, etc.) but is significant for the Type or for any string that is passed in as a value.

Policy File Examples

An example of two entries in a policy configuration file is

  // If the code is signed by "Duke", grant it read/write access to all 
  // files in /tmp:

  grant signedBy "Duke" {
    permission java.io.FilePermission "/tmp/*", "read,write";
  };

// Grant everyone the following permission: grant { permission java.util.PropertyPermission "java.vendor"; };

The contents of another sample policy configuration file appear below.

  grant signedBy "sysadmin", codeBase "file:/home/sysadmin/" {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
    permission java.security.SecurityPermission "Security.setProperty.*";
  };
This specifies that only applet code that was loaded from a signed JAR file (whose signature can be verified using the public key referenced by the alias name "sysadmin" in the user's keystore) from beneath the "/home/sysadmin/" directory on the local file system can call methods in the Security class to add or remove providers or to set Security properties.

Either component of the code source (or both) may be missing. An example where codeBase is missing is:

  grant signedBy "sysadmin" {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
};
If this policy is in effect, code that comes in a JAR File signed by "sysadmin" can add/remove providers - regardless of where the JAR File originated from.

An example without a signer is:

  grant codeBase "file:/home/sysadmin/" {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
};
In this case, code that comes from anywhere beneath the "/home/sysadmin/" directory on the local filesystem can add/remove providers. The code does not need to be signed.

An example where neither codeBase nor signedBy is included is:

  grant {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
};
Here, with both code source components missing, any code (regardless of where it originated from, or whether or not it is signed, or who signed it) can add/remove providers.

SEE ALSO