Merge "Add openflowjava release notes"
[docs.git] / docs / developer-guide / authentication-and-authorization-services.rst
1 Authentication, Authorization and Accounting (AAA) Services
2 ===========================================================
3
4 Overview
5 --------
6
7 Authentication, Authorization and Accounting (AAA) is a term for a
8 framework controlling access to resources, enforcing policies to use
9 those resources and auditing their usage. These processes are the
10 fundamental building blocks for effective network management and security.
11
12 Authentication provides a way of identifying a user, typically by
13 having the user enter a valid user name and valid password before access
14 is granted. The process of authentication is based on each user having a unique
15 set of criteria for gaining access. The AAA framework compares a user's
16 authentication credentials with other user credentials stored in a database.
17 If the credentials match, the user is granted access to the network.
18 If the credentials don't match, authentication fails and access is denied.
19
20 Authorization is the process of finding out what an authenticated user is
21 allowed to do within the system, which tasks can do, which API can call, etc.
22 The authorization process determines whether the user has the authority
23 to perform such actions.
24
25 Accounting is the process of logging the activity of an authenticated user,
26 for example, the amount of data a user has sent and/or received during a
27 session, which APIs called, etc.
28
29 Terms And Definitions
30 ^^^^^^^^^^^^^^^^^^^^^
31
32 AAA
33     Authentication, Authorization and Accounting.
34
35 Token
36     A claim of access to a group of resources on the controller.
37
38 Domain
39     A group of resources, direct or indirect, physical, logical, or
40     virtual, for the purpose of access control.
41
42 User
43     A person who either owns or has access to a resource or group of
44     resources on the controller.
45
46 Role
47     Opaque representation of a set of permissions, which is merely a
48     unique string as admin or guest.
49
50 Credential
51     Proof of identity such as user name and password, OTP, biometrics, or
52     others.
53
54 Client
55     A service or application that requires access to the controller.
56
57 Claim
58     A data set of validated assertions regarding a user, e.g. the role,
59     domain, name, etc.
60
61 IdP
62     Identity Provider.
63
64
65 Quick Start
66 -----------
67
68 Building
69 ^^^^^^^^
70 Get the code:
71
72 .. code-block:: bash
73
74     git clone https://git.opendaylight.org/gerrit/aaa
75
76 Build it:
77
78 .. code-block:: bash
79
80     cd aaa && mvn clean install
81
82
83 Installing
84 ^^^^^^^^^^
85
86 AAA is automatically installed upon installation of odl-restconf, but you can
87 install it yourself directly from the Karaf console through the following
88 command:
89
90 ::
91
92     feature:install odl-aaa-shiro
93
94 Pushing changes
95 ^^^^^^^^^^^^^^^
96
97 The following are basic instructions to push your contributions to the project's
98 GIT repository:
99
100 .. code-block:: bash
101
102     git add .
103     git commit -s
104     # make changes, add change id, etc.
105     git commit --amend
106     git push ssh://{username}@git.opendaylight.org:29418/aaa.git HEAD:refs/for/master
107
108 AAA Framework implementations
109 -----------------------------
110
111 Since Boron release, the OpenDaylight's AAA services are based on the
112 `Apache Shiro <https://shiro.apache.org/>`_ Java Security Framework. The main
113 configuration file for AAA is located at “etc/shiro.ini” relative to the
114 OpenDaylight Karaf home directory.
115
116 Known limitations
117 ^^^^^^^^^^^^^^^^^
118
119 The database (H2) used by ODL AAA Authentication store is not-cluster enabled.
120 When deployed in a clustered environment each node needs to have its AAA user
121 file synchronized using out of band means.
122
123 How to enable AAA
124 -----------------
125
126 AAA is enabled through installing the odl-aaa-shiro feature. The vast majority
127 of OpenDaylight's northbound APIs (and all RESTCONF APIs) are protected by AAA
128 by default when installing the +odl-restconf+ feature, since the odl-aaa-shiro
129 is automatically installed as part of them.
130
131 How to disable AAA
132 ------------------
133
134 Edit the “etc/shiro.ini” file and replace the following:
135
136 ::
137
138     /** = authcBasic
139
140 with
141
142 ::
143
144     /** = anon
145
146 Then, restart the Karaf process.
147
148 How application developers can leverage AAA to provide servlet security
149 -----------------------------------------------------------------------
150
151 In order to provide security to a servlet, add the following to the
152 servlet’s web.xml file as the first filter definition:
153
154 .. code-block:: xml
155
156     <context-param>
157       <param-name>shiroEnvironmentClass</param-name>
158       <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
159     </context-param>
160
161     <listener>
162         <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
163     </listener>
164
165     <filter>
166         <filter-name>ShiroFilter</filter-name>
167         <filter-class>org.opendaylight.aaa.shiro.filters.AAAShiroFilter</filter-class>
168     </filter>
169
170     <filter-mapping>
171         <filter-name>AAAShiroFilter</filter-name>
172         <url-pattern>/*</url-pattern>
173     </filter-mapping>
174
175 .. note::
176
177     It is very important to place this AAAShiroFilter as the first
178     javax.servlet.Filter, as Jersey applies Filters in the order they
179     appear within web.xml. Placing the AAAShiroFilter first ensures
180     incoming HTTP/HTTPS requests have proper credentials before any
181     other filtering is attempted.
182
183 AAA Realms
184 ----------
185
186 AAA plugin utilizes the Shiro Realms to support pluggable authentication &
187 authorization schemes. There are two parent types of realms:
188
189 -  AuthenticatingRealm
190
191    -  Provides no Authorization capability.
192
193    -  Users authenticated through this type of realm are treated
194       equally.
195
196 -  AuthorizingRealm
197
198    -  AuthorizingRealm is a more sophisticated AuthenticatingRealm,
199       which provides the additional mechanisms to distinguish users
200       based on roles.
201
202    -  Useful for applications in which roles determine allowed
203       capabilities.
204
205 OpenDaylight contains five implementations:
206
207 -  TokenAuthRealm
208
209    -  An AuthorizingRealm built to bridge the Shiro-based AAA service
210       with the h2-based AAA implementation.
211
212    -  Exposes a RESTful web service to manipulate IdM policy on a
213       per-node basis. If identical AAA policy is desired across a
214       cluster, the backing data store must be synchronized using an out
215       of band method.
216
217    -  A python script located at “etc/idmtool” is included to help
218       manipulate data contained in the TokenAuthRealm.
219
220    -  Enabled out of the box. This is the realm configured by default.
221
222 -  ODLJndiLdapRealm
223
224    -  An AuthorizingRealm built to extract identity information from IdM
225       data contained on an LDAP server.
226
227    -  Extracts group information from LDAP, which is translated into
228       OpenDaylight roles.
229
230    -  Useful when federating against an existing LDAP server, in which
231       only certain types of users should have certain access privileges.
232
233    -  Disabled out of the box.
234
235 -  ODLJndiLdapRealmAuthNOnly
236
237    -  The same as ODLJndiLdapRealm, except without role extraction.
238       Thus, all LDAP users have equal authentication and authorization
239       rights.
240
241    -  Disabled out of the box.
242
243 -  ODLActiveDirectoryRealm
244
245    -  Wraps the generic ActiveDirectoryRealm provided by Shiro. This allows for
246       enhanced logging as well as isolation of all realms in a single package,
247       which enables easier import by consuming servlets.
248
249    -  Disabled out of the box.
250
251 -  KeystoneAuthRealm
252
253    -  This realm authenticates OpenDaylight users against the OpenStack's
254       Keystone server by using the
255       `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
256       or later.
257
258    - Disabled out of the box.
259
260 .. note::
261
262     More than one Realm implementation can be specified. Realms are attempted
263     in order until authentication succeeds or all realm sources are exhausted.
264     Edit the **securityManager.realms = $tokenAuthRealm** property in shiro.ini
265     and add all the realms needed separated by commas.
266
267 TokenAuthRealm
268 ^^^^^^^^^^^^^^
269
270 How it works
271 ~~~~~~~~~~~~
272
273 The TokenAuthRealm is the default Authorization Realm deployed in OpenDaylight.
274 TokenAuthRealm uses a direct authentication mechanism as shown in the following
275 picture:
276
277 .. figure:: ./images/aaa/direct-authentication.png
278    :alt: TokenAuthRealm direct authentication mechanism
279
280    TokenAuthRealm direct authentication mechanism
281
282 A user presents some credentials (e.g., username/password) directly to the
283 OpenDaylight controller token endpoint /oauth2/token and receives an access
284 token, which then can be used to access protected resources on the controller.
285
286 How to access the H2 database
287 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288
289 The H2 database provides an optional front-end Web interface, which can be very
290 useful for new users. From the KARAF_HOME directory, you can run the following
291 command to enable the user interface:
292
293 .. code-block:: bash
294
295     java -cp ./data/cache/org.eclipse.osgi/bundles/217/1/.cp/h2-1.4.185.jar
296         org.h2.tools.Server -trace -pg -web -webAllowOthers -baseDir `pwd`
297
298
299 You can navigate to the following and login via the browser:
300
301 ::
302
303     http://{IP}:8082/
304
305 ODLJndiLdapRealm
306 ^^^^^^^^^^^^^^^^
307
308 How it works
309 ~~~~~~~~~~~~
310
311 LDAP integration is provided in order to externalize identity management.
312 This configuration allows federation with an external LDAP server.
313 The user’s OpenDaylight role parameters are mapped to corresponding LDAP
314 attributes as specified by the groupRolesMap. Thus, an LDAP operator can
315 provision attributes for LDAP users that support different OpenDaylight role
316 structures.
317
318 ODLJndiLdapRealmAuthNOnly
319 ^^^^^^^^^^^^^^^^^^^^^^^^^
320
321 How it works
322 ~~~~~~~~~~~~
323
324 This is useful for setups where all LDAP users are allowed equal access.
325
326 KeystoneAuthRealm
327 ^^^^^^^^^^^^^^^^^
328
329 How it works
330 ~~~~~~~~~~~~
331
332 This realm authenticates OpenDaylight users against the OpenStack's Keystone
333 server. This realm uses the
334 `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
335 or later.
336
337 .. figure:: ./images/aaa/keystonerealm-authentication.png
338    :alt: KeystoneAuthRealm authentication mechanism
339
340    KeystoneAuthRealm authentication/authorization mechanism
341
342 As can shown on the above diagram, once configured, all the RESTCONF APIs calls
343 will require sending **user**, **password** and optionally **domain** (1). Those
344 credentials are used to authenticate the call against the Keystone server (2) and,
345 if the authentication succeeds, the call will proceed to the MDSAL (3). The
346 credentials must be provisioned in advance within the Keystone Server. The user
347 and password are mandatory, while the domain is optional, in case it is not
348 provided within the REST call, the realm will default to (**Default**),
349 which is hard-coded. The default domain can be also configured through the
350 *shiro.ini* file (see the :doc:`AAA User Guide <../user-guide/authentication-and-authorization-services>`).
351
352 The protocol between the Controller and the Keystone Server (2) can be either
353 HTTPS or HTTP. In order to use HTTPS the Keystone Server's certificate
354 must be exported and imported on the Controller (see the :ref:`Certificate Management <Certificate Management>` section).
355
356 Authorization Configuration
357 ---------------------------
358
359 OpenDaylight supports two authorization engines at present, both of which are
360 roughly similar in behavior:
361
362 - Shiro-Based Authorization
363
364 - MDSAL-Based Dynamic Authorization
365
366 .. note::
367
368     The preferred mechanism for configuring AAA Authentication is the
369     MDSAL-Based Dynamic Authorization. Read the following section.
370
371 Shiro-Based Static Authorization
372 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373
374 OpenDaylight AAA has support for Role Based Access Control (RBAC) based
375 on the Apache Shiro permissions system. Configuration of the authorization
376 system is done off-line; authorization currently cannot be configured
377 after the controller is started. The Authorization provided by this mechanism
378 is aimed towards supporting coarse-grained security policies, the MDSAL-Based
379 mechanism allows for a more robust configuration capabilities. `Shiro-based
380 Authorization <http://shiro.apache.org/web.html#Web-%7B%7B%5Curls%5C%7D%7D>`_
381 describes how to configure the Authentication feature in detail.
382
383 .. notes::
384
385     The Shiro-Based Authorization that uses the *shiro.ini* URLs section to
386     define roles requirements is **deprecated** and **discouraged** since the
387     changes made to the file are only honored on a controller restart.
388
389     Shiro-Based Authorization is not **cluster-aware**, so the changes made on
390     the *shiro.ini* file have to be replicated on every controller instance
391     belonging to the cluster.
392
393     The URL patterns are matched relative to the Servlet context leaving room
394     for ambiguity, since many endpoints may match (i.e., "/restconf/modules" and
395     "/auth/modules" would both match a "/modules/\**" rule).
396
397 MDSAL-Based Dynamic Authorization
398 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
399 The MDSAL-Based Dynamic authorization uses the MDSALDynamicAuthorizationFilter
400 engine to restrict access to particular URL endpoint patterns. Users may define
401 a list of policies that are insertion-ordered. Order matters for that list of
402 policies, since the first matching policy is applied. This choice was made to
403 emulate behavior of the Shiro-Based Authorization mechanism.
404
405 A **policy** is a key/value pair, where the key is a **resource**
406 (i.e., a "URL pattern") and the value is a list of **permissions** for the
407 resource. The following describes the various elements of a policy:
408
409 - **Resource**: the resource is a string URL pattern as outlined by
410   Apache Shiro. For more information, see http://shiro.apache.org/web.html.
411
412 - **Description**: an optional description of the URL endpoint and why it is
413   being secured.
414
415 - **Permissions list**: a list of permissions for a particular policy. If more
416   than one permission exists in the permissions list they are evaluated using
417   logical "OR". A permission describes the prerequisites to perform HTTP
418   operations on a particular endpoint. The following describes the various
419   elements of a permission:
420
421   + **Role**: the role required to access the target URL endpoint.
422   + **Actions list**: a leaf-list of HTTP permissions that are allowed for a
423     Subject possessing the required role.
424
425 This an example on how to limit access to the modules endpoint:
426
427 ::
428
429     HTTP Operation:
430     put URL: /restconf/config/aaa:http-authorization/policies
431
432     headers: Content-Type: application/json Accept: application/json
433
434     body:
435       { "aaa:policies":
436         { "aaa:policies":
437           [ { "aaa:resource": "/restconf/modules/**",
438             "aaa:permissions": [ { "aaa:role": "admin",
439                                    "aaa:actions": [ "get",
440                                                     "post",
441                                                     "put",
442                                                     "patch",
443                                                     "delete"
444                                                   ]
445                                  }
446                                ]
447             }
448           ]
449         }
450       }
451
452 The above example locks down access to the modules endpoint (and any URLS
453 available past modules) to the "admin" role. Thus, an attempt from the OOB
454 *admin* user will succeed with 2XX HTTP status code, while an attempt from the
455 OOB *user* user will fail with HTTP status code 401, as the user *user* is not
456 granted the "admin" role.
457
458 Accounting Configuration
459 ------------------------
460
461 Accounting is handled through the standard slf4j logging mechanisms used by the
462 rest of OpenDaylight. Thus, one can control logging verbosity through
463 manipulating the log levels for individual packages and classes directly through
464 the Karaf console, JMX, or etc/org.ops4j.pax.logging.cfg. In normal operations,
465 the default levels exposed do not provide much information about AAA services;
466 this is due to the fact that logging can severely degrade performance.
467
468 All AAA logging is output to the standard karaf.log file. For debugging purposes
469 (i.e., to enable maximum verbosity), issue the following command:
470
471 ::
472
473     log:set TRACE org.opendaylight.aaa
474
475 Enable Successful/Unsuccessful Authentication Attempts Logging
476 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
477
478 By default, successful/unsuccessful authentication attempts are NOT logged. This
479 is due to the fact that logging can severely decrease REST performance.
480
481 It is possible to add custom AuthenticationListener(s) to the Shiro-based
482 configuration, allowing different ways to listen for successful/unsuccessful
483 authentication attempts. Custom AuthenticationListener(s) must implement
484 the org.apache.shiro.authc.AuthenticationListener interface.
485
486 Certificate Management
487 ----------------------
488
489 The **Certificate Management Service** is used to manage the keystores and
490 certificates at the OpenDaylight distribution to easily provides the TLS
491 communication.
492
493 The Certificate Management Service managing two keystores:
494
495 1. **OpenDaylight Keystore** which holds the OpenDaylight distribution
496    certificate self sign certificate or signed certificate from a root CA based
497    on generated certificate request.
498
499 2. **Trust Keystore** which holds all the network nodes certificates that shall
500    to communicate with the OpenDaylight distribution through TLS communication.
501
502 The Certificate Management Service stores the keystores (OpenDaylight & Trust)
503 as *.jks* files under configuration/ssl/ directory. Also the keystores
504 could be stored at the MD-SAL datastore in case OpenDaylight distribution
505 running at cluster environment. When the keystores are stored at MD-SAL,
506 the Certificate Management Service rely on the **Encryption-Service** to encrypt
507 the keystore data before storing it to MD-SAL and decrypted at runtime.
508
509 How to use the Certificate Management Service to manage the TLS communication
510 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
511
512 The following are the steps to configure the TLS communication within your
513 feature or module:
514
515 1. It is assumed that there exists an already created OpenDaylight distribution
516    project following `this guide
517    <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype#Part_1_-_Build_with_a_simple_.27Example.27_module>`_.
518
519 2. In the implementation bundle the following artifact must be added to its
520    *pom.xml* file as dependency.
521
522 .. code-block:: xml
523
524     <dependency>
525       <groupId>org.opendaylight.aaa</groupId>
526       <artifactId>aaa-cert</artifactId>
527       <version>0.5.0-SNAPSHOT</version>
528     </dependency>
529
530 3. Using the provider class in the implementation bundle needs to define a
531    variable holding the Certificate Manager Service as in the following example:
532
533 .. code-block:: java
534
535     import org.opendaylight.aaa.cert.api.ICertificateManager;
536     import org.opendaylight.controller.md.sal.binding.api.DataBroker;
537
538     public class UseCertManagerExampleProvider {
539       private final DataBroker dataBroker;
540       private final ICertificateManager caManager;
541
542       public EncSrvExampleProvider(final DataBroker dataBroker, final ICertificateManager caManager) {
543         this.dataBroker = dataBroker;
544         this.caManager = caManager;
545       }
546       public SSLEngine createSSLEngine() {
547         final SSLContext sslContext = caManager.getServerContext();
548         if (sslContext != null) {
549           final SSLEngine sslEngine = sslContext.createSSLEngine();
550           sslEngine.setEnabledCipherSuites(caManager.getCipherSuites());
551           // DO the Implementation
552           return sslEngine;
553         }
554       }
555       public void init() {
556           // TODO
557       }
558       public void close() {
559           // TODO
560       }
561     }
562
563 4. The Certificate Manager Service provides two main methods that are needed to
564    establish the *SSLEngine* object, *getServerContext()* and *getCipherSuites()*
565    as the above example shows. It also provides other methods such as
566    *getODLKeyStore()* and *getTrustKeyStore()* that gives access to the
567    OpenDaylight and Trust keystores.
568
569 5. Now the *ICertificateManager* need to be passed as an argument to the
570    *UseCertManagerExampleProvider* within the implementation bundle blueprint
571    configuration. The following example shows how:
572
573 .. code-block:: xml
574
575     <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
576       xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
577       odl:use-default-for-reference-types="true">
578       <reference id="dataBroker"
579         interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
580         odl:type="default" />
581       <reference id="aaaCertificateManager"
582         interface="org.opendaylight.aaa.cert.api.ICertificateManager"
583         odl:type="default-certificate-manager" />
584       <bean id="provider"
585         class="org.opendaylight.UseCertManagerExample.impl.UseCertManagerExampleProvider"
586         init-method="init" destroy-method="close">
587         <argument ref="dataBroker" />
588         <argument ref="aaaCertificateManager" />
589       </bean>
590     </blueprint>
591
592 6. After finishing the bundle implementation the feature module needs to be
593    updated to include the *aaa-cert* feature in its feature bundle pom.xml file.
594
595 .. code-block:: xml
596
597     <properties>
598       <aaa.version>0.5.0-SNAPSHOT</aaa.version>
599     </properties>
600     <dependency>
601       <groupId>org.opendaylight.aaa</groupId>
602       <artifactId>features-aaa</artifactId>
603       <version>${aaa.version}</version>
604       <classifier>features</classifier>
605       <type>xml</type>
606     </dependency>
607
608 7. Now, in the feature.xml file add the Certificate Manager Service feature and
609    its repository.
610
611 .. code-block:: xml
612
613     <repository>mvn:org.opendaylight.aaa/features-aaa/{VERSION}/xml/features</repository>
614
615 The Certificate Manager Service feature can be included inside the
616 implementation bundle feature as shown in the following example:
617
618 .. code-block:: xml
619
620     <feature name='odl-UseCertManagerExample' version='${project.version}'
621       description='OpenDaylight :: UseCertManagerExample'>
622       <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
623       <feature version='${aaa.version}'>odl-aaa-cert</feature>
624       <bundle>mvn:org.opendaylight.UseCertManagerExample/UseCertManagerExample-impl/{VERSION}</bundle>
625     </feature>
626
627 8. Now the project can be built and the OpenDaylight distribution started to
628    continue with the configuration process. See the User Guide for more details.
629
630 Encryption Service
631 ------------------
632
633 The **AAA Encryption Service** is used to encrypt the OpenDaylight users'
634 passwords and TLS communication certificates. This section shows how to use the
635 AAA Encryption Service with an OpenDaylight distribution project to encrypt data.
636
637 1. It is assumed that there exists an already created OpenDaylight distribution
638    project following `this guide
639    <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype#Part_1_-_Build_with_a_simple_.27Example.27_module>`_.
640
641 2. In the implementation bundle the following artifact must be added to its
642    *pom.xml* file as dependency.
643
644 .. code-block:: xml
645
646     <dependency>
647       <groupId>org.opendaylight.aaa</groupId>
648       <artifactId>aaa-encrypt-service</artifactId>
649       <version>0.5.0-SNAPSHOT</version>
650     </dependency>
651
652 3. Using the provider class in the implementation bundle needs to define a
653    variable holding the Encryption Service as in the following example:
654
655 .. code-block:: java
656
657     import org.opendaylight.aaa.encrypt.AAAEncryptionService;
658     import org.opendaylight.controller.md.sal.binding.api.DataBroker;
659
660     public class EncSrvExampleProvider {
661     private final DataBroker dataBroker;
662       private final AAAEncryptionService encryService;
663
664       public EncSrvExampleProvider(final DataBroker dataBroker, final AAAEncryptionService encryService) {
665         this.dataBroker = dataBroker;
666         this.encryService = encryService;
667       }
668       public void init() {
669         // TODO
670       }
671       public void close() {
672         // TODO
673       }
674     }
675
676 The AAAEncryptionService can be used to encrypt and decrypt any data based on
677 project's needs.
678
679 4. Now the *AAAEncryptionService* needs to be passed as an argument to the
680    *EncSrvExampleProvider* within the implementation bundle blueprint
681    configuration. The following example shows how:
682
683 .. code-block:: xml
684
685     <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
686       xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
687       odl:use-default-for-reference-types="true">
688       <reference id="dataBroker"
689         interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
690         odl:type="default" />
691       <reference id="encryService" interface="org.opendaylight.aaa.encrypt.AAAEncryptionService"/>
692       <bean id="provider"
693         class="org.opendaylight.EncSrvExample.impl.EncSrvExampleProvider"
694         init-method="init" destroy-method="close">
695         <argument ref="dataBroker" />
696         <argument ref="encryService" />
697       </bean>
698     </blueprint>
699
700 5. After finishing the bundle implementation the feature module needs to be
701    updated to include the *aaa-encryption-service* feature in its feature bundle
702    pom.xml file.
703
704 .. code-block:: xml
705
706     <dependency>
707       <groupId>org.opendaylight.aaa</groupId>
708       <artifactId>features-aaa</artifactId>
709       <version>${aaa.version}</version>
710       <classifier>features</classifier>
711       <type>xml</type>
712     </dependency>
713
714 It is also necessary to add the *aaa.version* in the properties section:
715
716 .. code-block:: xml
717
718     <properties>
719       <aaa.version>0.5.0-SNAPSHOT</aaa.version>
720     </properties>
721
722 6. Now, in the feature.xml file add the Encryption Service feature and its
723    repository.
724
725 .. code-block:: xml
726
727     <repository>mvn:org.opendaylight.aaa/features-aaa/{VERSION}/xml/features</repository>
728
729 The Encryption Service feature can be included inside the implementation bundle
730 feature as shown in the following example:
731
732 .. code-block:: xml
733
734     <feature name='odl-EncSrvExample' version='${project.version}' description='OpenDaylight :: EncSrvExample'>
735       <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
736       <feature version='${aaa.version}'>odl-aaa-encryption-service</feature>
737       <feature version='${project.version}'>odl-EncSrvExample-api</feature>
738       <bundle>mvn:org.opendaylight.EncSrvExample/EncSrvExample-impl/{VERSION}</bundle>
739     </feature>
740
741 7. Now the project can be built and the OpenDaylight distribution started to
742    continue with the configuration process. See the User Guide for more details.