Définir les autorisations d'accès aux métadonnées avec Open Metadata Architecture

Depuis la SAS® Management Console, il n'est pas possible d'appliquer un contrôle d'accès sur plusieurs objets en une seule manipulation : un administrateur doit sélectionner chaque objet pour appliquer des autorisations ou des restrictions.

Cet article explique comment appliquer des contrôles d'accès (ACT) à un grand nombre d'objets dans les métadonnées en programmation.
Cet article est destiné aux administrateurs de SAS ayant une bonne connaissance de l'objet « modèle de métadonnées » et du langage de programmation SAS. Cela est nécessaire pour mettre en œuvre un certain niveau de protection des ressources dans les métadonnées.
 
Dans la partie "Illustration avec des exemples », nous approfondirons la façon d'appliquer une ACT personnalisée pour un objet de type PhysicalTable avec des exemples de code.

Préparation de l'environnement

Vous avez besoin de tester le code dans un environnement de développement pour veiller à ce que les métadonnées ne soient pas altérées en raison d'essais et d'erreurs.

  • Veiller à ce que le serveur de métadonnées soit en place et fonctionne correctement
  • Veiller à ce que les utilisateurs ne soient pas connectés au serveur de métadonnées
  • Faire une sauvegarde des métadonnées en production avant toute utilisation du code fourni dans le présent document

Pré-requis: Bonne connaissance des objets du modèle de métadonnées.

Illustration

A - Ajout d'une table (Type : PHYSICALTABLE) dans une bibliothèque existante :

Supposons qu'une bibliothèque «SAMPLE» de type SAS/BASE existe déjà dans les métadonnées. Maintenant, nous ajoutons dans les métadonnées (car la table existe déjà physiquement) la table TEST à la bibliothèque «SAMPLE».

LIBNAME SAMPLE "C:\SAS9\EntBIServer\Lev1\Data"; 

Proc metalib;
Omr (library="SAMPLE" user="nbdel162\sasadm"
        password="AdminAdmin1"
        metaserver="nbdel162"
        port='8561'
         repName=Foundation);
   *Update_rule=(delete);    /* syncs entire directory */
   Select ("test");    /* syncs one table */
   Report;
Run;

B - Création d'une ACT personnalisée :

Pour notre exemple, nous allons créer une ACT nommée «TEST_USER_ACT». Imaginons que l’ACT définisse les autorisations suivantes :

  • on refuse toutes les permissions au groupe «SASUSERS»
  • on autorise readmetadata et writemetadata au groupe «MYUSERS»

E tape 1 : nous devons extraire l'objet de référence ID associé à chaque autorisation

options metauser="nbdel162\sasadm"
        metapass="AdminAdmin1"
        metaserver="nbdel162"
        metaport=8561
       Metarepository=Foundation;

filename request temp ;
filename response temp ;
/* Retrieve the object reference of each permission */
data _null_ ;
   file request ;
   put '<GetMetadataObjects>' ;
   put '<Reposid>$METAREPOSITORY</Reposid>' ;
   put '<Type>Permission</Type>' ;
   put '<NS>SAS</NS>' ;
   put '<Flags>260</Flags>' ;
   put '<Options>' ;
   put '<Templates>' ;
   put '<Permission Type=""/>' ;
   put '</Templates>' ;
   put '</Options>' ;
   put '</GetMetadataObjects>' ;
run ;


proc metadata verbose header=full
   in=request
   out=response ;
run ;

filename SXLEMAP temp;

data _null_;
    file SXLEMAP;
    put '<?xml version="1.0" ?>';
    put '<SXLEMAP name="Permissions"  version="1.0">';
    put '<TABLE name="Permission">';
    put ' <TABLE-PATH syntax="XPath">/GetMetadataObjects/Objects/Permission</TABLE-PATH>';

    put '    <COLUMN name="Id">';
    put '        <PATH syntax="XPath">/GetMetadataObjects/Objects/Permission/@Id</PATH>';
    put '        <TYPE>character</TYPE>';
    put '        <DATATYPE>string</DATATYPE>';
    put '        <LENGTH>17</LENGTH>';
    put '    </COLUMN>';

    put '    <COLUMN name="Name">';
    put '        <PATH syntax="XPath">/GetMetadataObjects/Objects/Permission/@Name</PATH>';
    put '        <TYPE>character</TYPE>';
    put '        <DATATYPE>string</DATATYPE>';
    put '        <LENGTH>60</LENGTH>';
    put '    </COLUMN>';

    put '    <COLUMN name="Type">';
    put '        <PATH syntax="XPath">/GetMetadataObjects/Objects/Permission/@Type</PATH>';
    put '        <TYPE>character</TYPE>';
    put '        <DATATYPE>string</DATATYPE>';
    put '        <LENGTH>5</LENGTH>';
    put '  </COLUMN>';
    put '</TABLE>';
    put '</SXLEMAP>';

    run;
libname   response xml xmlmap=SXLEMAP access=READONLY;

data _null_ ;
   set response.permission ;
   call symput(catx('_',name,type),strip(id)) ;
run ;
%put _user_ ;

Etape 2 : nous devons ensuite construire l’ACT - «TEST_USER_ACT» avec les autorisations appropriées pour les groupes ou l’utilisateur désiré.

data _null_ ;
   retain sasusers_ig_uri ;
   length type $32 sasusers_ig_uri t_uri ig_uri lib_uri $ 17 line $ 100 ;
   file request ;
/* Retrieve the object reference of group SASUSERS */
   rc=metadata_resolve("omsobj:IdentityGroup?@Name='SASUSERS'",type,sasusers_ig_uri) ;
   *put sasusers_ig_uri=;
/* Retrieve the object reference of group MYUSERS*/
   rc=metadata_resolve("omsobj:IdentityGroup?@Name='MYUSERS'",type,ig_uri) ;
   *put ig_uri=;

   dept= 'TEST_USER_ACT';
   put "<AddMetadata>" ;
   put "<Metadata>" ;

      line=cats("<AccessControlTemplate Name='",dept,"'>") ;
      put line ;
      put "<AccessControlItems>" ;
      line=cats("<AccessControlEntry Name='",cats(dept,"_deny_all"),"'>") ;
      put line ;
      put "<Identities>" ;
      line="<IdentityGroup ObjRef=""" || strip(sasusers_ig_uri) || """/>" ;
      put line ;
      put "</Identities>" ;
      put "<Permissions>" ;
      put "<Permission ObjRef=""&READMETADATA_DENY""/>" ;
      put "<Permission ObjRef=""&WRITEMETADATA_DENY""/>" ;
      put "<Permission ObjRef=""&CHECKINMETADATA_DENY""/>" ;
      put "<Permission ObjRef=""&READ_DENY""/>" ;
      put "<Permission ObjRef=""&WRITE_DENY""/>" ;
      put "<Permission ObjRef=""&DELETE_DENY""/>" ;
      put "<Permission ObjRef=""&ADMINISTER_DENY""/>" ;
      put "<Permission ObjRef=""&CREATE_DENY""/>" ;
      put "</Permissions>" ;
      put "</AccessControlEntry>" ;
      line=cats("<AccessControlEntry Name='",cats(dept,"_grant_rm_rw"),"'>") ;
      put line ;
      put "<Identities>" ;
      line="<IdentityGroup ObjRef=""" || strip(ig_uri) || """/>" ;
      put line ;
      put "</Identities>" ;
      put "<Permissions>" ;
      put "<Permission ObjRef=""&READMETADATA_GRANT""/>" ;
      put "<Permission ObjRef=""&WRITEMETADATA_GRANT""/>" ;
      put "</Permissions>" ;
      put "</AccessControlEntry>" ;
      put "</AccessControlItems>" ;
      put "</AccessControlTemplate>" ;

    put "</Metadata>" ;
    put "<ReposId>$METAREPOSITORY</ReposId>" ;
    put "<NS>SAS</NS>" ;
    put "<Flags>268435456</Flags>" ;
    put "<Options/>" ;
    put "</AddMetadata>" ;
 
run ;

proc metadata verbose header=full
   in=request
   out=response ;
run ;

C -  Finalement, nous appliquons l’ACT « TEST_USER_ACT» à l'objet «TEST» de type PhysicalTable :

%macro applyACT(objName,objType,actName);

options metauser="nbdel162\sasadm"
        metapass="AdminAdmin1"
        metaserver="nbdel162"
        metaport=8561
  Metarepository=Foundation;

filename request temp ;
filename response temp ;

data _null_ ;
   length type $32 t_uri act_uri ace_uri $ 17 line $ 100 ;
   file request ;
/* Retrieve the object reference of a given object*/
   line="omsobj:&objType?@Name='&objName'";
   rc=metadata_resolve(line,type,t_uri) ;
  
/* Retrieve the object reference of a custom ACT*/
   line="omsobj:AccessControlTemplate?@Name='&actName'";
   rc=metadata_resolve(line,type,act_uri) ;
      
/* Retrieve the object reference of the ACE associated with the concerned object*/
line="omsobj:AccessControlEntry?AccessControlEntry[/Objects/&objType[@Name='&objName']]";
   rc=metadata_resolve(line,type,ace_uri) ;
     
   put "<UpdateMetadata>" ;
   put "<Metadata>" ;

      line="<PhysicalTable Id='"|| strip(t_uri)|| "' >";
 put line ;
      put "<AccessControls Function='Replace'>" ;
      line=cats("<AccessControlTemplate ObjRef='"|| strip(act_uri)|| "' />") ;
      put line ;
   if strip(ace_uri) <> '' then
  do;
  line=cats("<AccessControlEntry ObjRef='"|| strip(ace_uri)|| "' />") ;
       put line ;
  end;
   put "</AccessControls>";
   put "</PhysicalTable>" ;

   if strip(ace_uri) <> '' then
  do; 
   line=cats("<AccessControlEntry Id='"|| strip(ace_uri)|| "'>") ;
   put line ;
   line=cats("<Permissions Function='Replace'/>") ;
   put line ;
   line=cats("<Identities Function='Replace'/>") ;
   put line ;
   line=cats("</AccessControlEntry>") ;
   put line ;
      end;
   put "<DeletedObjects/>" ;
    put "</Metadata>" ;
    put "<ReposId>$METAREPOSITORY</ReposId>" ;
    put "<NS>SAS</NS>" ;
    put "<Flags>402654208</Flags>" ;
    put "<Options/>" ;
    put "</UpdateMetadata>" ;
 
run ;

proc metadata verbose header=full
   in=request
   out=response ;
run ;

%mend;

%applyACT(TEST,PhysicalTable,TEST_USER_ACT);

Ce macro-programme pourrait être appelé dans une boucle composée de tous les objets qui doivent avoir les mêmes autorisations. 

Annexe - Liens utiles

SAS 9.1.3 Open Metadata Interface: Reference, Second Edition

SAS® Intelligence Platform - Data Administration Guide


Anitha DATCHANAMOURTY
Consultant Support Clients SAS France